28 Commits

Author SHA1 Message Date
4d9c134f04 add Gandi zone info input + sync br/lorien home files 2024-09-02 20:45:54 +02:00
c1750624c9 add engines alias 2024-07-27 09:21:17 +02:00
e177a0716f improve more/less 2024-07-27 09:20:08 +02:00
6aed1cfbfd emacs: use vundo instead of undo-tree, .bashrc: cleanup. 2024-03-24 19:47:07 +01:00
cc5ae859a0 config lsp-ui-doc, etc... (see comments)
- configure lsp-ui-doc
- separate multiple cursor section
- Makefile-mode: Change fill-column to high, to prevent stupid indent
- Fix c-mode "/*" extra space on <return>
2024-03-02 09:45:55 +01:00
79955bb355 base.sh: add readline support for interective mode 2024-02-19 12:09:20 +01:00
b0f1f53865 Add negative decimal input, regex for prefixes, bits per int detection 2024-02-01 09:34:49 +01:00
f1fe945ecd add long options example 2024-01-31 13:25:03 +01:00
30a2954514 Fix bin() output and split(); add padding option. 2024-01-31 13:10:42 +01:00
d26c60e565 add ~/.local/bin in PATH 2024-01-26 07:54:34 +01:00
512c08ea31 remove less --auto-buffers option 2024-01-25 17:46:16 +01:00
4a14195bcd add bashrc.root 2024-01-23 09:52:04 +01:00
6dbd254992 add grep aliases, please shellcheck 2024-01-21 21:18:49 +01:00
ee68ec34c2 add base.sh 2024-01-21 21:16:09 +01:00
e8a218f7cb merge lorien/eowyn 2024-01-20 20:38:57 +01:00
63388aaa7a rename dot-files to non-dot, move pdf viewer to .bashrc.br 2024-01-20 19:52:36 +01:00
11b7cf40eb Add .bash_profile to avoid dup $HOME/bin in PATH(stupid Debian) 2024-01-20 19:12:04 +01:00
9801503eab Merge branch 'master' of github.com:braoult/Tools 2024-01-20 18:06:14 +01:00
de35fe60e7 typos 2024-01-20 15:25:12 +01:00
85e0ca1af5 add eowyn bashrc, add syncdir() 2024-01-20 15:19:05 +01:00
3d7f388fb8 vardir(): add '+' as default script to source 2023-12-29 18:46:45 +01:00
1aef3f1196 lorien.el: adjust for brlib 2023-12-29 18:45:50 +01:00
3da006ed73 emacs: Fix modeline VC symbols, update lorien.el opened files 2023-12-27 08:20:40 +01:00
6f58b0bddc replace multiple prj aliases with functions (and helper function) 2023-12-27 07:32:45 +01:00
608d80b3d8 add share/sync/COPYING 2023-12-27 07:19:49 +01:00
fc28134385 remove brlib 2023-12-27 06:45:53 +01:00
6ccb5f2264 cleanup 2023-12-24 17:38:53 +01:00
fb203bbcae move debug.h & pool.h main() to test dir (unmodified, can't compile) 2023-12-24 17:37:27 +01:00
51 changed files with 1103 additions and 5686 deletions

3
.gitignore vendored
View File

@@ -6,6 +6,3 @@
/LICENSE.*
/test/
/todo/
/c/lib/
/c/obj/
compile_commands.json

View File

@@ -1,8 +1,11 @@
### Some GNU/Linux tools, for fun...
### Some personal GNU/Linux tools.
#### bash
- **trans.sh**: a [linguee.com](https://linguee.com) based command-line translator.
- **sync.sh**: a rsync/ssh backup tool.
- **sync-view.sh**: view ~sync.sh~ file backups versions.
- **sync-conf-example.sh**: configuration example.
- **dup-live-disk.sh**: duplicate (possibly live) disk partitions.
- **dup-live-disk.sh**: duplicate (**possibly live**) disk partitions.
- **gen-password.sh**: a password generator.
- **base.sh**: bases 2/8/10/16 conversions.

View File

@@ -1,11 +1,10 @@
### Some GNU/Linux tools, for fun...
#### bash
### Some bash scripts, that I needed at some time...
- [**trans.sh**](trans.sh): a [linguee.com](https://linguee.com) based command-line translator.
- [**sync.sh**](sync.sh): a rsync/ssh backup tool.
- [**sync-conf-example.sh**](share/sync/sync-conf-example.sh): configuration example.
- [**sync-view.sh**](sync-view.sh): view `sync.sh` file backups versions.
- [**dup-live-disk.sh**](dup-live-disk.sh): duplicate (possibly live) disk partitions.
- [**gen-password.sh**](gen-password.sh): a password generator
- [**share/gen-password**](share/gen-password): [diceware](https://en.wikipedia.org/wiki/Diceware)-like word lists.
- [**base**](base.sh): bases 2/8/10/16 conversions.

324
bash/base.sh Executable file
View File

@@ -0,0 +1,324 @@
#!/usr/bin/env bash
#
# base.sh - convert decimal numbers from/to base 2, 8, 10 and 16.
#
# (C) Bruno Raoult ("br"), 2024
# Licensed under the GNU General Public License v3.0 or later.
# Some rights reserved. See COPYING.
#
# You should have received a copy of the GNU General Public License along with this
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
#
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
#
CMDNAME=${0##*/} # script name
# some default values (blocks separator padchar)
# Attention: For output base 10, obase is 1
declare -i ibase=0 obase=0 padding=0 prefix=1 ogroup=0 intbits
# find out int size (bits) - suppose 2-complement, and 8 bits char
printf -v _b "%x" -1
(( intbits = ${#_b} * 4 ))
declare -rA _bases=( # -f/-b accepted values
[2]=2 [b]=2 [B]=2
[8]=8 [o]=8 [O]=8
[10]=10 [d]=10 [D]=10
[16]=16 [h]=16 [H]=16
[a]=-1 [g]=-1
)
declare -A _pad=( # group separator
[2]=" " [8]=" " [10]="," [16]=" "
)
declare -rA _ogroup=( # group size
[2]=8 [8]=3 [10]=3 [16]=4
)
declare -rA _oprefix=( # output prefix
[2]="2#" [8]="0" [10]="" [16]="0x"
)
usage() {
printf "usage: %s [OPTIONS] [NUMBER]...\n" "$CMDNAME"
printf "Use '%s -h' for more help\n" "$CMDNAME"
}
help() {
cat << _EOF
usage: $CMDNAME [OPTIONS] [NUMBER]...
-f, --from=BASE input base, see BASE below. Default is "g"
-t, --to=BASE output base, see BASE below. Default is "a"
-b, -o, -d, -x equivalent to -t2, -t8, -t10, -t16"
-g, --group=[SEP] group output (see OUTPUT below)
-p, --padding 0-pad output on block boundary (implies -g)
-n, --noprefix remove base prefixes in output
-h, --help this help
-- end of options
$CMDNAME output the NUMBERS arguments in different bases. If no NUMBER is
given, standard input will be used.
BASE
2, b, B binary
8, o, O, 0 octal
10, d, D decimal
16, h, H, 0x hexadecimal
a, g all/any: Default, guess format for '-f', output all
bases for '-t'
INPUT NUMBER
If input base is not specified, some prefixes are supported.
'b' or '2/' for binary, '0', 'o' or '8/' for octal, '0x', 'x' or
'16/' for hexadecimal, and 'd' or '10/' for decimal.
If no above prefix is found, decimal is assumed.
Decimal input may be signed or unsigned, with limits imposed by current
Bash (here: $intbits bits).
OUTPUT
Decimal output is always unsigned.
By default, the input number is shown converted in the 4 supported
bases (16, 10, 8, 2, in this order), separated by one tab character.
Without '-n' option, all output numbers but decimal will be prefixed:
'2#' for binary, '0' for octal, '0x' for hexadecimal, making them
usable for input in some otilities such as bash(1).]
With '-g' option, number digits will be grouped by 3 (octal,
decimal), 4 (hexadecimal), or 8 (binary). If no SEP character is given,
the separator will be ',' (comma) for decimal, space otherwise.
This option may be useless for default output, with multiple numbers
on one line.
The '-p' option add 0 padding up to the base grouping boundary.
EXAMPLES
Converting number in hexadecimal, decimal, octal, and binary, with or without
prefixes. Here, '\t' separator is shown as space:
$ $CMDNAME 0
0x0 0 0 2#0
$ $CMDNAME 123456
0x1e240 123456 0361100 2#11110001001000000
$ $CMDNAME -n 2/100
4 4 4 100
$ $CMDNAME -n 0x1e240
1e240 123456 361100 11110001001000000
Binary output, no prefix, grouped output:
$ $CMDNAME -bng 0x1e240
1 11100010 01000000
Negative input (decimal only):
$ $CMDNAME -x -- -1
0xffffffffffffffff
Input base indication, left padding binary output, no prefix:
$ $CMDNAME -nbp -f8 361100
00000001 11100010 01000000
Set group separator. Note that the separator *must* immediately follow the '-g'
option, without spaces:
$ $CMDNAME -nxg: 123456
1:e240
Long options, with separator and padding:
$ $CMDNAME --to=16 --noprefix --padding --group=: 12345
0001:e240
TODO
Add option for signed/unsigned integer output.
Remove useless octal output ?
_EOF
}
zero_pad() {
local n="$1" str="$2"
printf "%0.*d%s" $(( n - ${#str} % n)) 0 "$str"
}
split() {
local base="$1" str="$2"
local res="$str" sep=${_pad[$base]}
local -i n=${_ogroup[$base]}
(( padding )) && str=$(zero_pad "${_ogroup[$base]}" "$str")
if (( ogroup )); then
res=""
while (( ${#str} )); do
if (( ${#str} <= n )); then # finished
res="${str}${res:+$sep$res}"
break
fi
res="${str: -n}${res:+$sep$res}"
str="${str:0:-n}"
done
fi
printf "%s" "$res"
}
bin() {
local str=""
local -i n dec="$1"
# take care of negative numbers, as >> operator keeps the sign.
# 'intbits' is size of integer in bits in current shell.
for (( n = 0 ; dec && (n < intbits); n++ )); do
str="$(( dec & 1 ))$str"
(( dec >>= 1 ))
done
printf "%s\n" "${str:-0}"
}
hex() {
printf "%lx" "$1"
}
dec() {
printf "%lu" "$1"
}
oct() {
printf "%lo" "$1"
}
declare -a args=()
parse_opts() {
# short and long options
local sopts="f:t:bodxg::pnh"
local lopts="from:,to:,group::,padding,noprefix,help"
# set by options
local tmp=""
if ! tmp=$(getopt -o "$sopts" -l "$lopts" -n "$CMDNAME" -- "$@"); then
usage
exit 1
fi
eval set -- "$tmp"
while true; do
case "$1" in
"-f"|"--from")
ibase=${_bases[$2]}
if (( ! ibase )); then
usage
exit 1
fi
shift
;;
"-t"|"--to")
obase=${_bases[$2]}
if (( ! obase )); then
usage
exit 1
fi
shift
;;
"-b") obase=2 ;;
"-o") obase=8 ;;
"-d") obase=1 ;;
"-x") obase=16 ;;
"-g"|"--group")
ogroup=1
if [[ -n "$2" ]]; then
for i in 2 8 10 16; do _pad["$i"]="$2"; done
fi
shift
;;
"-p"|"--padding") ogroup=1; padding=1 ;;
"-n"|"--noprefix") prefix=0 ;;
"-h"|"--help") help ; exit 0 ;;
"--") shift; break ;;
*) usage; echo "Internal error [$1]!" >&2; exit 1 ;;
esac
shift
done
# next are numbers to convert, if any
if (($# > 0)); then
args=("$@")
fi
}
addprefix() {
local base="$1" number="$2" _prefix=""
if (( prefix )); then
if [[ $base != 8 || $number != "0" ]]; then
_prefix="${_oprefix[$base]}"
fi
fi
printf "%s%s" "$_prefix" "$number"
}
stripprefix() {
[[ $1 =~ ^(0x|b|o|d|x|.*/) ]]
printf "%s" "${1#"${BASH_REMATCH[1]}"}"
}
guessbase() {
local input="$1"
local -i base=0
if [[ $input =~ ^(b|2/) ]]; then
base=2
elif [[ $input =~ ^(0x|x|16/) ]]; then
base=16
elif [[ $input =~ ^(0|o|8/) ]]; then
base=8
elif [[ $input =~ ^(d|10/) ]]; then
base=10
fi
return $(( base ? base : 10 ))
}
doit() {
local number="$2" multi="" val inum
local -i base=$1 decval _obase=$obase
if (( base <= 0 )); then
guessbase "$number"
base=$?
fi
inum=$(stripprefix "$number")
# convert input value to decimal
(( base == 10 )) && (( decval = inum ))
(( base != 10 )) && (( decval = "$base#$inum" ))
# mask for desired output: 1=decimal, others are same as base
if (( ! _obase )); then
(( _obase = 1|2|8|16 ))
multi=$'\t'
fi
if (( _obase & 16 )); then
val=$(addprefix 16 "$(split 16 "$(hex $decval)")")
printf "%s%s" "$val" "$multi"
fi
if (( _obase & 1 )); then
val=$(addprefix 10 "$(split 10 "$(dec $decval)")")
printf "%s%s" "$val" "$multi"
fi
if (( _obase & 8 )); then
val=$(addprefix 8 "$(split 8 "$(oct $decval)")")
printf "%s%s" "$val" "$multi"
fi
if (( _obase & 2 )); then
val=$(addprefix 2 "$(split 2 "$(bin $decval)")")
printf "%s%s" "$val" "$multi"
fi
printf "\n"
}
parse_opts "$@"
if ! (( ${#args[@]} )); then
while read -era line; do
for input in "${line[@]}"; do
doit "ibase" "$input"
done
done
else
for input in "${args[@]}"; do
doit "$ibase" "$input"
done
fi
exit 0

View File

@@ -565,8 +565,8 @@ parse_opts() {
local c2="" c3=""
local -i i
if ! tmp=$(getopt -o "$sopts" -l "$lopts" -n "$CMD" -- "$@"); then
log "Use '$CMD --help' or '$CMD --man' for help."
if ! tmp=$(getopt -o "$sopts" -l "$lopts" -n "$CMDNAME" -- "$@"); then
log "Use '$CMD --help' or 'zob $CMDNAME --man' for help."
exit 1
fi

View File

@@ -1,59 +0,0 @@
# Tools Makefile
#
# Copyright (C) 2023 Bruno Raoult ("br")
# Licensed under the GNU General Public License v3.0 or later.
# Some rights reserved. See COPYING.
#
# You should have received a copy of the GNU General Public License along with this
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
#
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
#
SHELL := /bin/bash
CC := gcc
BEAR := bear
CFLAGS += -std=gnu11
CFLAGS += -O2
CFLAGS += -g
CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -march=native
CFLAGS += -Wmissing-declarations
CFLAGS += -Wno-unused-result
# for gprof
#CFLAGS += -pg
# Next one may be useful for valgrind (some invalid instructions)
#CFLAGS += -mno-tbm
CPPFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
CPPFLAGS += -DDEBUG_POOL # memory pools management
INCDIR := ./include
LIBDIR := ./lib
OBJDIR := ./obj
BRLIBDIR := ./brlib
LIBNAME := br_$(shell uname -m)
#LIB := lib$(LIBNAME)
all: brlib
#export LD_LIBRARY_PATH = $(LIBDIR)
.PHONY: all brlib clean
all: brlib
brlib:
$(MAKE) -C $(BRLIBDIR)
bear ccls:
@echo building ccls language server compilation database
$(MAKE) -C $(BRLIBDIR) ccls
clean:
@echo cleaning brlib.
@$(MAKE) -C $(BRLIBDIR) clean

View File

@@ -1,281 +0,0 @@
# brlib Makefile - GNU make only
#
# Copyright (C) 2021-2023 Bruno Raoult ("br")
# Licensed under the GNU General Public License v3.0 or later.
# Some rights reserved. See COPYING.
#
# You should have received a copy of the GNU General Public License along with this
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
#
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
#
# important to know where exactly is project root dir
ROOTDIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
SHELL := /bin/bash
CC := gcc
LD := ld
BEAR := bear
TOUCH := touch
RM := rm
RMDIR := rmdir
SRCDIR := ./src
INCDIR := ./include
OBJDIR := ./obj
LIBDIR := ./lib
BINDIR := ./bin
DEPDIR := ./dep
SRC := $(wildcard $(SRCDIR)/*.c) # brlib sources
SRC_FN := $(notdir $(SRC)) # source basename
OBJ := $(addprefix $(OBJDIR)/,$(SRC_FN:.c=.o))
LIB := br_$(shell uname -m) # library name
SLIB := $(addsuffix .a, $(LIBDIR)/lib$(LIB)) # static lib
DLIB := $(addsuffix .so, $(LIBDIR)/lib$(LIB)) # dynamic lib
DEP_FN := $(SRC_FN) $(LIBSRC_FN)
DEP := $(addprefix $(DEPDIR)/,$(DEP_FN:.c=.d))
##################################### emacs projectile/ccls
PRJROOT := .projectile
CCLSROOT := .ccls-root
CCLSCMDS := compile_commands.json
##################################### pre-processor flags
CPPFLAGS := -I$(INCDIR)
#CPPFLAGS += -DDEBUG # global
CPPFLAGS += -DDEBUG_DEBUG # enable log() functions
#CPPFLAGS += -DDEBUG_DEBUG_C # log() funcs debug
PPFLAGS += -DDEBUG_DEBUG # activate logs funcs
CPPFLAGS += -DDEBUG_POOL # mem pools
# remove extraneous spaces (due to spaces before comments)
CPPFLAGS := $(strip $(CPPFLAGS))
##################################### compiler flags
CFLAGS := -std=gnu11
CFLAGS += -O2
CFLAGS += -g
CFLAGS += -Wall
CFLAGS += -Wextra
CFLAGS += -march=native
CFLAGS += -Wmissing-declarations
CFLAGS += -Wno-unused-result
CFLAGS += -fPIC
# for gprof
#CFLAGS += -pg
# Next one may be useful for valgrind (some invalid instructions)
# CFLAGS += -mno-tbm
CFLAGS := $(strip $(CFLAGS))
##################################### archiver/linker/dependency flags
ARFLAGS := rcs
LDFLAGS := -L$(LIBDIR)
DEPFLAGS = -MMD -MP -MF $(DEPDIR)/$*.d
##################################### General targets
.PHONY: all compile clean cleanall
all: libs
compile: objs
clean: cleandep cleanobj cleanlib cleanbin
cleanall: clean cleandepdir cleanobjdir cleanlibdir cleanbindir
# setup emacs projectile/ccls
emacs: emacs-setup
# update compile-commands.json
ccls: $(CCLSCMDS)
##################################### cleaning functions
# rmfiles - deletes a list of files in a directory if they exist.
# $(1): the directory
# $(2): the list of files to delete
# $(3): The string to include in action output - "cleaning X files."
# see: https://stackoverflow.com/questions/6783243/functions-in-makefiles
#
# Don't use wildcard like "$(DIR)/*.o", so we can control mismatches between
# list and actual files in directory.
# See rmdir below.
define rmfiles
@#echo "rmfiles=+$(1)+"
$(eval $@_EXIST = $(wildcard $(1)))
@#echo "existfile=+${$@_EXIST}+"
@if [[ -n "${$@_EXIST}" ]]; then \
echo "cleaning $(2) files." ; \
$(RM) ${$@_EXIST} ; \
fi
endef
# rmdir - deletes a directory if it exists.
# $(1): the directory
# $(2): The string to include in action output - "removing X dir."
#
# Don't use $(RM) -rf, to control unexpected dep files.
# See rmfile above.
define rmdir
@#echo "rmdir +$(1)+"
$(eval $@_EXIST = $(wildcard $(1)))
@#echo "existdir=+${$@_EXIST}+"
@if [[ -n "${$@_EXIST}" ]]; then \
echo "removing $(2) dir." ; \
$(RMDIR) ${$@_EXIST} ; \
fi
endef
##################################### dirs creation
.PHONY: alldirs
ALLDIRS := $(DEPDIR) $(OBJDIR) $(LIBDIR) $(BINDIR)
alldirs: $(ALLDIRS)
# Here, we have something like:
# a: a
# a will be built if (1) older than a, or (2) does not exist. Here only (2).
$(ALLDIRS): $@
@echo creating $@ directory.
@mkdir -p $@
##################################### Dependencies files
.PHONY: cleandep cleandepdir
-include $(wildcard $(DEP))
# Don't use $(DEPDIR)/*.d, to control mismatches between dep and src files.
# See second rule below.
cleandep:
$(call rmfiles,$(DEP),depend)
@#echo cleaning dependency files.
@#$(RM) -f $(DEP)
cleandepdir:
$(call rmdir,$(DEPDIR),depend)
@#[ -d $(DEPDIR) ] && echo cleaning depend files && $(RM) -f $(DEP) || true
##################################### objects
.PHONY: objs cleanobj cleanobjdir
objs: $(OBJ)
cleanobj:
$(call rmfiles,$(OBJ),brlib object)
cleanobjdir:
$(call rmdir,$(OBJDIR),brlib objects)
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR) $(DEPDIR)
@echo compiling $< "->" $@.
$(CC) -c $(DEPFLAGS) $(CPPFLAGS) $(CFLAGS) $< -o $@
##################################### brlib libraries
.PHONY: libs cleanlib cleanlibdir
libs: $(DLIB) $(SLIB)
cleanlib:
$(call rmfiles,$(DLIB) $(SLIB),library)
cleanlibdir:
$(call rmdir,$(LIBDIR),libraries)
#$(DLIB): CFLAGS += -fPIC
$(DLIB): LDFLAGS += -shared
$(DLIB): $(OBJ) | $(LIBDIR)
@echo "building $@ shared library ($?)."
$(CC) $(CFLAGS) $(LDFLAGS) $? -o $@
$(SLIB): $(OBJ) | $(LIBDIR)
@echo "building $@ static library ($?)."
$(AR) $(ARFLAGS) $@ $? > /dev/null
##################################### brchess binaries
.PHONY: targets cleanbin cleanbindir
targets: $(TARGET)
cleanbin:
$(call rmfiles,$(TARGET),binary)
cleanbindir:
$(call rmdir,$(BINDIR),binaries)
##################################### pre-processed (.i) and assembler (.s) output
%.i: %.c
@echo generating $@
@$(CC) -E $(CPPFLAGS) $(CFLAGS) $< -o $@
%.s: %.c
@echo generating $@
@$(CC) -S -fverbose-asm $(CPPFLAGS) $(CFLAGS) $< -o $@
##################################### LSP (ccls)
.PHONY: emacs-setup
PRJROOT := .projectile
CCLSROOT := .ccls-root
CCLSFILE := .ccls
CCLSCMDS := compile_commands.json
emacs-setup: $(PRJROOT) $(CCLSROOT) $(CCLSCMDS)
#$(CCLSFILE):
# @echo "creating CCLS's $@ project root file."
# echo '%compile_commands.json' > $@
$(CCLSROOT) $(PRJROOT):
@if [[ $(@) = $(PRJROOT) ]] ; \
then \
echo "creating Emacs's projectile root file." ; \
else \
echo "creating Emacs's ccls root file." ; \
fi
@$(TOUCH) $@
# generate compile_commands.json.
# TODO: add includes and Makefile dependencies.
# also, if cclsfile is newer than sources, no need to clean objects file
# (and to run bear).
# maybe run cleanobj cleanlibobj in commands ?
$(CCLSCMDS): cleanobj $(SRC) | $(CCLSROOT)
@echo "Generating ccls compile commands file ($@)."
@$(BEAR) -- make compile
#.PHONY: bear
#bear: cleanobj cleanlibobj Makefile | $(CCLSROOT)
# @$(BEAR) -- make compile
##################################### valgrind (mem check)
.PHONY: memcheck
VALGRIND := valgrind
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all
VALGRINDFLAGS += --track-origins=yes --sigill-diagnostics=yes
VALGRINDFLAGS += --quiet --show-error-list=yes
VALGRINDFLAGS += --log-file=valgrind.out
# We need to suppress libreadline leaks here. See :
# https://stackoverflow.com/questions/72840015
VALGRINDFLAGS += --suppressions=etc/libreadline.supp
memcheck: targets
@$(VALGRIND) $(VALGRINDFLAGS) $(BINDIR)/brchess
##################################### Makefile debug
.PHONY: showflags wft
showflags:
@echo CFLAGS: "$(CFLAGS)"
@echo CPPFLAGS: $(CPPFLAGS)
@echo DEPFLAGS: $(DEPFLAGS)
@echo LDFLAGS: $(LDFLAGS)
wtf:
@printf "ROOTDIR=+%s+\n\n" "$(ROOTDIR)"
@printf "OBJDIR=%s\n\n" "$(OBJDIR)"
@printf "OBJ=%s\n\n" "$(OBJ)"

View File

@@ -1,499 +0,0 @@
/* bits.h - bits functions.
*
* Copyright (C) 2021-2022 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#ifndef _BITS_H
#define _BITS_H
#include <stdint.h>
#include <stdbool.h>
#include <bits/wordsize.h> /* defines __WORDSIZE: 32 or 64 */
void bits_implementation(void);
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
/* no plan to support 32bits for now...
* #if __WORDSIZE != 64
* #error "Only 64 bits word size supported."
* #endif
*/
/* fixed-size types
*/
typedef int64_t s64;
typedef int32_t s32;
typedef int16_t s16;
typedef int8_t s8;
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
/* convenience types
*/
typedef long long int llong;
typedef unsigned long long int ullong;
typedef unsigned long int ulong;
typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned char uchar;
/* char is a special case, as it can be signed or unsigned
*/
typedef signed char schar;
/* define common types sizes
*/
#define BITS_PER_CHAR 8
#ifndef BITS_PER_SHORT
#define BITS_PER_SHORT (BITS_PER_CHAR * sizeof (short))
#endif
#ifndef BITS_PER_INT
#define BITS_PER_INT (BITS_PER_CHAR * sizeof (int))
#endif
#ifndef BITS_PER_LONG
#define BITS_PER_LONG (BITS_PER_CHAR * sizeof (long))
#endif
#ifndef BITS_PER_LLONG
#define BITS_PER_LLONG (BITS_PER_CHAR * sizeof (long long))
#endif
/* count set bits: 10101000 -> 3
* ^ ^ ^
*/
static __always_inline int popcount64(u64 n)
{
# if __has_builtin(__builtin_popcountl)
return __builtin_popcountl(n);
# else
int count = 0;
while (n) {
count++;
n &= (n - 1);
}
return count;
# endif
}
static __always_inline int popcount32(u32 n)
{
# if __has_builtin(__builtin_popcount)
return __builtin_popcount(n);
# else
int count = 0;
while (n) {
count++;
n &= (n - 1);
}
return count;
# endif
}
/* count trailing zeroes : 00101000 -> 3
* ^^^
*/
static __always_inline int ctz64(u64 n)
{
# if __has_builtin(__builtin_ctzl)
return __builtin_ctzl(n);
# elif __has_builtin(__builtin_clzl)
return __WORDSIZE - (__builtin_clzl(n & -n) + 1);
# else
return popcount64((n & -n) - 1);
# endif
}
static __always_inline int ctz32(u32 n)
{
# if __has_builtin(__builtin_ctz)
return __builtin_ctzl(n);
# elif __has_builtin(__builtin_clz)
return __WORDSIZE - (__builtin_clz(n & -n) + 1);
# else
return popcount32((n & -n) - 1);
# endif
}
/* clz - count leading zeroes : 00101000 -> 2
* ^^
*/
static __always_inline int clz64(u64 n)
{
# if __has_builtin(__builtin_clzl)
return __builtin_clzl(n);
# else
u64 r, q;
r = (n > 0xFFFFFFFF) << 5; n >>= r;
q = (n > 0xFFFF) << 4; n >>= q; r |= q;
q = (n > 0xFF ) << 3; n >>= q; r |= q;
q = (n > 0xF ) << 2; n >>= q; r |= q;
q = (n > 0x3 ) << 1; n >>= q; r |= q;
r |= (n >> 1);
return 64 - r - 1;
# endif
}
static __always_inline int clz32(u32 n)
{
# if __has_builtin(__builtin_clz)
return __builtin_clz(n);
# else
u32 r, q;
r = (n > 0xFFFF) << 4; n >>= r;
q = (n > 0xFF ) << 3; n >>= q; r |= q;
q = (n > 0xF ) << 2; n >>= q; r |= q;
q = (n > 0x3 ) << 1; n >>= q; r |= q;
r |= (n >> 1);
return 32 - r - 1;
# endif
}
/* fls - find last set : 00101000 -> 6
* ^
*/
static __always_inline int fls64(u64 n)
{
if (!n)
return 0;
return 64 - clz64(n);
}
static __always_inline int fls32(u32 n)
{
if (!n)
return 0;
return 32 - clz32(n);
}
/* find first set : 00101000 -> 4
* ^
*/
static __always_inline uint ffs64(u64 n)
{
# if __has_builtin(__builtin_ffsl)
return __builtin_ffsl(n);
# elif __has_builtin(__builtin_ctzl)
if (n == 0)
return (0);
return __builtin_ctzl(n) + 1;
# else
return popcount64(n ^ ~-n);
# endif
}
static __always_inline uint ffs32(u32 n)
{
# if __has_builtin(__builtin_ffs)
return __builtin_ffs(n);
# elif __has_builtin(__builtin_ctz)
if (n == 0)
return (0);
return __builtin_ctz(n) + 1;
# else
return popcount32(n ^ ~-n);
# endif
}
/* rolXX/rorXX are taken from kernel's <linux/bitops.h> are are:
* SPDX-License-Identifier: GPL-2.0
*/
/**
* rol64 - rotate a 64-bit value left
* @word: value to rotate
* @shift: bits to roll
*/
static inline u64 rol64(u64 word, unsigned int shift)
{
return (word << (shift & 63)) | (word >> ((-shift) & 63));
}
/**
* ror64 - rotate a 64-bit value right
* @word: value to rotate
* @shift: bits to roll
*/
static inline u64 ror64(u64 word, unsigned int shift)
{
return (word >> (shift & 63)) | (word << ((-shift) & 63));
}
/**
* rol32 - rotate a 32-bit value left
* @word: value to rotate
* @shift: bits to roll
*/
static inline u32 rol32(u32 word, unsigned int shift)
{
return (word << (shift & 31)) | (word >> ((-shift) & 31));
}
/**
* ror32 - rotate a 32-bit value right
* @word: value to rotate
* @shift: bits to roll
*/
static inline u32 ror32(u32 word, unsigned int shift)
{
return (word >> (shift & 31)) | (word << ((-shift) & 31));
}
/**
* rol16 - rotate a 16-bit value left
* @word: value to rotate
* @shift: bits to roll
*/
static inline u16 rol16(u16 word, unsigned int shift)
{
return (word << (shift & 15)) | (word >> ((-shift) & 15));
}
/**
* ror16 - rotate a 16-bit value right
* @word: value to rotate
* @shift: bits to roll
*/
static inline u16 ror16(u16 word, unsigned int shift)
{
return (word >> (shift & 15)) | (word << ((-shift) & 15));
}
/**
* rol8 - rotate an 8-bit value left
* @word: value to rotate
* @shift: bits to roll
*/
static inline u8 rol8(u8 word, unsigned int shift)
{
return (word << (shift & 7)) | (word >> ((-shift) & 7));
}
/**
* ror8 - rotate an 8-bit value right
* @word: value to rotate
* @shift: bits to roll
*/
static inline u8 ror8(u8 word, unsigned int shift)
{
return (word >> (shift & 7)) | (word << ((-shift) & 7));
}
/**
* __ilog2 - non-constant log of base 2 calculators
* - the arch may override these in asm/bitops.h if they can be implemented
* more efficiently than using fls() and fls64()
* - the arch is not required to handle n==0 if implementing the fallback
*/
static __always_inline __attribute__((const))
int __ilog2_u64(u64 n)
{
return fls64(n) - 1;
}
static __always_inline __attribute__((const))
int __ilog2_u32(u32 n)
{
return fls32(n) - 1;
}
/**
* is_power_of_2() - check if a value is a power of two
* @n: the value to check
*
* Determine whether some value is a power of two, where zero is
* *not* considered a power of two.
* Return: true if @n is a power of 2, otherwise false.
*/
static inline __attribute__((const))
bool is_power_of_2(unsigned long n)
{
return (n != 0 && ((n & (n - 1)) == 0));
}
/**
* __roundup_pow_of_two() - round up to nearest power of two
* @n: value to round up
*/
static inline __attribute__((const))
u64 __roundup_pow_of_two(u64 n)
{
return 1UL << fls64(n - 1);
}
/**
* __rounddown_pow_of_two() - round down to nearest power of two
* @n: value to round down
*/
static inline __attribute__((const)) u64 __rounddown_pow_of_two(u64 n)
{
return 1UL << (fls64(n) - 1);
}
/**
* ilog2 - log base 2 of 32-bit or a 64-bit unsigned value
* @n: parameter
*
* constant-capable log of base 2 calculation
* - this can be used to initialise global variables from constant data, hence
* the massive ternary operator construction
*
* selects the appropriately-sized optimised version depending on sizeof(n)
*/
#define ilog2(n) \
( \
__builtin_constant_p(n) ? \
((n) < 2 ? 0 : \
63 - __builtin_clzll(n)) : \
(sizeof(n) <= 4) ? \
__ilog2_u32(n) : \
__ilog2_u64(n) \
)
/**
* roundup_pow_of_two - round the given value up to nearest power of two
* @n: parameter
*
* round the given value up to the nearest power of two
* - the result is undefined when n == 0
* - this can be used to initialise global variables from constant data
*/
#define roundup_pow_of_two(n) \
( \
__builtin_constant_p(n) ? ( \
((n) == 1) ? 1 : \
(1UL << (ilog2((n) - 1) + 1)) \
) : \
__roundup_pow_of_two(n) \
)
/**
* rounddown_pow_of_two - round the given value down to nearest power of two
* @n: parameter
*
* round the given value down to the nearest power of two
* - the result is undefined when n == 0
* - this can be used to initialise global variables from constant data
*/
#define rounddown_pow_of_two(n) \
( \
__builtin_constant_p(n) ? ( \
(1UL << ilog2(n))) : \
__rounddown_pow_of_two(n) \
)
static inline __attribute_const__ int __order_base_2(unsigned long n)
{
return n > 1 ? ilog2(n - 1) + 1 : 0;
}
/**
* order_base_2 - calculate the (rounded up) base 2 order of the argument
* @n: parameter
*
* The first few values calculated by this routine:
* ob2(0) = 0
* ob2(1) = 0
* ob2(2) = 1
* ob2(3) = 2
* ob2(4) = 2
* ob2(5) = 3
* ... and so on.
*/
#define order_base_2(n) \
( \
__builtin_constant_p(n) ? ( \
((n) == 0 || (n) == 1) ? \
0 : \
ilog2((n) - 1) + 1) : \
__order_base_2(n) \
)
static inline __attribute__((const)) int __bits_per(unsigned long n)
{
if (n < 2)
return 1;
if (is_power_of_2(n))
return order_base_2(n) + 1;
return order_base_2(n);
}
/**
* bits_per - calculate the number of bits required for the argument
* @n: parameter
*
* This is constant-capable and can be used for compile time
* initializations, e.g bitfields.
*
* The first few values calculated by this routine:
* bf(0) = 1
* bf(1) = 1
* bf(2) = 2
* bf(3) = 2
* bf(4) = 3
* ... and so on.
*/
#define bits_per(n) \
( \
__builtin_constant_p(n) ? ( \
((n) == 0 || (n) == 1) ? \
1 : \
ilog2(n) + 1 : \
__bits_per(n) \
)
/** bit_for_each - iterate over an u64/u32 bits
* @pos: an int used as current bit
* @tmp: a temp u64/u32 used as temporary storage
* @ul: the u64/u32 to loop over
*
* Usage:
* u64 u=139, _t; // u=b10001011
* int cur;
* bit_for_each64(cur, _t, u) {
* printf("%d\n", cur);
* }
* This will display the position of each bit set in ul: 1, 2, 4, 8
*
* I should probably re-think the implementation...
*/
#define bit_for_each64(pos, tmp, ul) \
for (tmp = ul, pos = ffs64(tmp); tmp; tmp &= (tmp - 1), pos = ffs64(tmp))
#define bit_for_each32(pos, tmp, ul) \
for (tmp = ul, pos = ffs32(tmp); tmp; tmp &= (tmp - 1), pos = ffs32(tmp))
/** or would it be more useful (counting bits from zero instead of 1) ?
*/
#define bit_for_each64_2(pos, tmp, ul) \
for (tmp = ul, pos = ctz64(tmp); tmp; tmp ^= 1UL << pos, pos = ctz64(tmp))
#define bit_for_each32_2(pos, tmp, ul) \
for (tmp = ul, pos = ctz32(tmp); tmp; tmp ^= 1U << pos, pos = ctz32(tmp))
#endif /* _BITS_H */

View File

@@ -1,224 +0,0 @@
/* br.h - misc macros.
*
* Copyright (C) 2021-2022 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
* Some parts are taken from Linux's kernel <linux/kernel.h> and others, and are :
* SPDX-License-Identifier: GPL-2.0
*
* This header contains generic stuff.
*/
#ifndef _BR_H
#define _BR_H
#include "struct-group.h"
/* Indirect stringification. Doing two levels allows the parameter to be a
* macro itself. For example, compile with -DFOO=bar, __stringify(FOO)
* converts to "bar".
*/
#define __stringify_1(x...) #x
#define __stringify(x...) __stringify_1(x)
/* generate a (maybe) unique id.
*/
#define ___PASTE(x, y) x##y
#define __PASTE(x, y) ___PASTE(x, y)
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
/* unused/used parameters/functions
* https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-unused-function-attribute
* https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-unused-type-attribute
* https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-unused-variable-attribute
* https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-unused-label-attribute
* https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-used-function-attribute
* https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-used-variable-attribute
*/
#define __unused __attribute__((__unused__))
#define __used __attribute__((__used__))
/* see https://lkml.org/lkml/2018/3/20/845 for explanation of this monster
*/
#define __is_constexpr(x) \
(sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))
/*
* min()/max()/clamp() macros must accomplish three things:
*
* - avoid multiple evaluations of the arguments (so side-effects like
* "x++" happen only once) when non-constant.
* - perform strict type-checking (to generate warnings instead of
* nasty runtime surprises). See the "unnecessary" pointer comparison
* in __typecheck().
* - retain result as a constant expressions when called with only
* constant expressions (to avoid tripping VLA warnings in stack
* allocation usage).
*/
#define __typecheck(x, y) \
(!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
#define __no_side_effects(x, y) \
(__is_constexpr(x) && __is_constexpr(y))
#define __safe_cmp(x, y) \
(__typecheck(x, y) && __no_side_effects(x, y))
#define __cmp(x, y, op) ((x) op (y) ? (x) : (y))
#define __cmp_once(x, y, unique_x, unique_y, op) ({ \
typeof(x) unique_x = (x); \
typeof(y) unique_y = (y); \
__cmp(unique_x, unique_y, op); })
#define __careful_cmp(x, y, op) \
__builtin_choose_expr(__safe_cmp(x, y), \
__cmp(x, y, op), \
__cmp_once(x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y), op))
#define __pure __attribute__((__pure__))
/**
* min - return minimum of two values of the same or compatible types
* @x: first value
* @y: second value
*/
#define min(x, y) __careful_cmp(x, y, <)
/**
* max - return maximum of two values of the same or compatible types
* @x: first value
* @y: second value
*/
#define max(x, y) __careful_cmp(x, y, >)
/**
* min3 - return minimum of three values
* @x: first value
* @y: second value
* @z: third value
*/
#define min3(x, y, z) min((typeof(x))min(x, y), z)
/**
* max3 - return maximum of three values
* @x: first value
* @y: second value
* @z: third value
*/
#define max3(x, y, z) max((typeof(x))max(x, y), z)
/**
* min_not_zero - return the minimum that is _not_ zero, unless both are zero
* @x: value1
* @y: value2
*/
#define min_not_zero(x, y) ({ \
typeof(x) __x = (x); \
typeof(y) __y = (y); \
__x == 0 ? __y : ((__y == 0) ? __x : min(__x, __y)); })
/**
* clamp - return a value clamped to a given range with strict typechecking
* @val: current value
* @lo: lowest allowable value
* @hi: highest allowable value
*
* This macro does strict typechecking of @lo/@hi to make sure they are of the
* same type as @val. See the unnecessary pointer comparisons.
*/
#define clamp(val, lo, hi) min((typeof(val))max(val, lo), hi)
/*
* ..and if you can't take the strict
* types, you can specify one yourself.
*
* Or not use min/max/clamp at all, of course.
*/
/**
* min_t - return minimum of two values, using the specified type
* @type: data type to use
* @x: first value
* @y: second value
*/
#define min_t(type, x, y) __careful_cmp((type)(x), (type)(y), <)
/**
* max_t - return maximum of two values, using the specified type
* @type: data type to use
* @x: first value
* @y: second value
*/
#define max_t(type, x, y) __careful_cmp((type)(x), (type)(y), >)
/**
* clamp_t - return a value clamped to a given range using a given type
* @type: the type of variable to use
* @val: current value
* @lo: minimum allowable value
* @hi: maximum allowable value
*
* This macro does no typechecking and uses temporary variables of type
* @type to make all the comparisons.
*/
#define clamp_t(type, val, lo, hi) min_t(type, max_t(type, val, lo), hi)
/**
* clamp_val - return a value clamped to a given range using val's type
* @val: current value
* @lo: minimum allowable value
* @hi: maximum allowable value
*
* This macro does no typechecking and uses temporary variables of whatever
* type the input argument @val is. This is useful when @val is an unsigned
* type and @lo and @hi are literals that will otherwise be assigned a signed
* integer type.
*/
#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi)
/**
* swap - swap values of @a and @b
* @a: first value
* @b: second value
*/
#define swap(a, b) \
do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
/**
* ARRAY_SIZE - get the number of elements in array @arr
* @arr: array to be sized
*/
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
/**
* abs - return absolute value of an argument
* @x: the value. If it is unsigned type, it is converted to signed type first.
* char is treated as if it was signed (regardless of whether it really is)
* but the macro's return type is preserved as char.
*
* Return: an absolute value of x.
*/
#define abs(x) __abs_choose_expr(x, long long, \
__abs_choose_expr(x, long, \
__abs_choose_expr(x, int, \
__abs_choose_expr(x, short, \
__abs_choose_expr(x, char, \
__builtin_choose_expr( \
__builtin_types_compatible_p(typeof(x), char), \
(char)({ signed char __x = (x); __x<0?-__x:__x; }), \
((void)0)))))))
#define __abs_choose_expr(x, type, other) __builtin_choose_expr( \
__builtin_types_compatible_p(typeof(x), signed type) || \
__builtin_types_compatible_p(typeof(x), unsigned type), \
({ signed type __x = (x); __x < 0 ? -__x : __x; }), other)
#endif /* _BR_H */

View File

@@ -1,71 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _BR_BUG_H
#define _BR_BUG_H
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "likely.h"
#include "debug.h"
/* BUG functions inspired by Linux kernel's <asm/bug.h>
*/
#define panic() exit(0xff)
/*
* Don't use BUG() or BUG_ON() unless there's really no way out; one
* example might be detecting data structure corruption in the middle
* of an operation that can't be backed out of. If the (sub)system
* can somehow continue operating, perhaps with reduced functionality,
* it's probably not BUG-worthy.
*
* If you're tempted to BUG(), think again: is completely giving up
* really the *only* solution? There are usually better options, where
* users don't need to reboot ASAP and can mostly shut down cleanly.
*/
#define BUG() do { \
fprintf(stderr, "BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
panic(); \
} while (0)
#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while (0)
/*
* WARN(), WARN_ON(), WARN_ON_ONCE, and so on can be used to report
* significant kernel issues that need prompt attention if they should ever
* appear at runtime.
*
* Do not use these macros when checking for invalid external inputs
* (e.g. invalid system call arguments, or invalid data coming from
* network/devices), and on transient conditions like ENOMEM or EAGAIN.
* These macros should be used for recoverable kernel issues only.
* For invalid external inputs, transient conditions, etc use
* pr_err[_once/_ratelimited]() followed by dump_stack(), if necessary.
* Do not include "BUG"/"WARNING" in format strings manually to make these
* conditions distinguishable from kernel issues.
*
* Use the versions with printk format strings to provide better diagnostics.
*/
#define __WARN() do { \
fprintf(stderr, "WARNING: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
} while (0)
#define __WARN_printf(arg...) do { \
vfprintf(stderr, arg); \
} while (0)
#define WARN_ON(condition) ({ \
int __ret_warn_on = !!(condition); \
if (unlikely(__ret_warn_on)) \
__WARN(); \
unlikely(__ret_warn_on); \
})
#define WARN(condition, format...) ({ \
int __ret_warn_on = !!(condition); \
if (unlikely(__ret_warn_on)) \
__WARN_printf(format); \
unlikely(__ret_warn_on); \
})
#endif /* _BR_BUG_H */

View File

@@ -1,30 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* adaptation of Linux kernel's <linux/container_of.h>
*/
#ifndef _BR_CONTAINER_OF_H
#define _BR_CONTAINER_OF_H
/* Are two types/vars the same type (ignoring qualifiers)? */
#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
/**
* typeof_member -
*/
#define typeof_member(T, m) typeof(((T*)0)->m)
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member) ({ \
void *__mptr = (void *)(ptr); \
_Static_assert(__same_type(*(ptr), ((type *)0)->member) || \
__same_type(*(ptr), void), \
"pointer type mismatch in container_of()"); \
((type *)(__mptr - offsetof(type, member))); })
#endif /* BR_CONTAINER_OF_H */

View File

@@ -1,115 +0,0 @@
/* debug.h - debug/log management.
*
* Copyright (C) 2021-2023 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#ifndef DEBUG_H
#define DEBUG_H
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <br.h>
#define NANOSEC 1000000000 /* nano sec in sec */
#define MILLISEC 1000000 /* milli sec in sec */
#define _printf __attribute__ ((format (printf, 6, 7)))
#ifdef DEBUG_DEBUG
void debug_init(int level, FILE *stream, bool flush);
void debug_level_set(int level);
int debug_level_get(void);
void debug_stream_set(FILE *stream);
long long debug_timer_elapsed(void);
void debug_flush_set(bool flush);
void _printf debug(int level, bool timestamp,
int indent, const char *src,
int line, const char *fmt, ...);
#else /* DEBUG_DEBUG */
static inline void debug_init(__unused int level,
__unused FILE *stream,
__unused bool flush) {}
static inline void debug_level_set(__unused int level) {}
static inline int debug_level_get(void) {return 0;}
static inline void debug_stream_set(__unused FILE *stream) {}
static inline long long debug_timer_elapsed(void) {return 0LL;}
static inline void debug_flush_set(__unused bool level) {}
static inline void _printf debug(__unused int level, __unused bool timestamp,
__unused int indent, __unused const char *src,
__unused int line, __unused const char *fmt, ...) {}
#endif /* DEBUG_DEBUG */
#undef _printf
/**
* log - simple log (no function name, no indent, no timestamp)
* @level: log level
* @fmt: printf format string
* @args: subsequent arguments to printf
*/
#define log(level, fmt, args...) \
debug((level), false, 0, NULL, 0, fmt, ##args)
/**
* log_i - log with indent (no function name, no timestamp)
* @level: log level
* @fmt: printf format string
* @args: subsequent arguments to printf
*
* Output example:
* >>>>val=2
*/
#define log_i(level, fmt, args...) \
debug((level), false, (level), NULL, 0, fmt, ##args)
/**
* log_f - log with function name (no indent name, no timestamp)
* @level: log level
* @fmt: printf format string
* @args: subsequent arguments to printf
*
* Output example:
* [function] val=2
*/
#define log_f(level, fmt, args...) \
debug((level), false, 0, __func__, 0, fmt, ##args)
/**
* log_if - log with function name and line number (no indent name, no timestamp)
* @level: log level
* @fmt: printf format string
* @args: subsequent arguments to printf
*
* Output example:
* >>>> [function:15] val=2
*/
#define log_if(level, fmt, args...) \
debug((level), false, (level), __func__, __LINE__, fmt, ##args)
/**
* log_it - log with function name, line number, indent, and timestamp
* @level: log level
* @fmt: printf format string
* @args: subsequent arguments to printf
*
* Output example:
* >>>> [function:15] val=2
*/
#define log_it(level, fmt, args...) \
debug((level), true, (level), __func__, __LINE__, fmt, ##args)
#endif /* DEBUG_H */

View File

@@ -1,172 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _BR_HASH_H
#define _BR_HASH_H
/* adaptation of Linux kernel's <linux/hash.h> and <linux/stringhash.h>
*/
/* Fast hashing routine for ints, longs and pointers.
(C) 2002 Nadia Yvette Chambers, IBM */
#include <asm/bitsperlong.h>
#include "bits.h"
#include "br.h"
/*
* The "GOLDEN_RATIO_PRIME" is used in ifs/btrfs/brtfs_inode.h and
* fs/inode.c. It's not actually prime any more (the previous primes
* were actively bad for hashing), but the name remains.
*/
#if __BITS_PER_LONG == 32
#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_32
#define hash_long(val, bits) hash_32(val, bits)
#elif __BITS_PER_LONG == 64
#define hash_long(val, bits) hash_64(val, bits)
#define GOLDEN_RATIO_PRIME GOLDEN_RATIO_64
#else
#error Wordsize not 32 or 64
#endif
/*
* This hash multiplies the input by a large odd number and takes the
* high bits. Since multiplication propagates changes to the most
* significant end only, it is essential that the high bits of the
* product be used for the hash value.
*
* Chuck Lever verified the effectiveness of this technique:
* http://www.citi.umich.edu/techreports/reports/citi-tr-00-1.pdf
*
* Although a random odd number will do, it turns out that the golden
* ratio phi = (sqrt(5)-1)/2, or its negative, has particularly nice
* properties. (See Knuth vol 3, section 6.4, exercise 9.)
*
* These are the negative, (1 - phi) = phi**2 = (3 - sqrt(5))/2,
* which is very slightly easier to multiply by and makes no
* difference to the hash distribution.
*/
#define GOLDEN_RATIO_32 0x61C88647
#define GOLDEN_RATIO_64 0x61C8864680B583EBull
/*
* The _generic versions exist only so lib/test_hash.c can compare
* the arch-optimized versions with the generic.
*
* Note that if you change these, any <asm/hash.h> that aren't updated
* to match need to have their HAVE_ARCH_* define values updated so the
* self-test will not false-positive.
*/
#ifndef HAVE_ARCH__HASH_32
#define __hash_32 __hash_32_generic
#endif
static inline u32 __hash_32_generic(u32 val)
{
return val * GOLDEN_RATIO_32;
}
static inline u32 hash_32(u32 val, unsigned int bits)
{
/* High bits are more random, so use them. */
return __hash_32(val) >> (32 - bits);
}
#ifndef HAVE_ARCH_HASH_64
#define hash_64 hash_64_generic
#endif
static __always_inline u32 hash_64_generic(u64 val, unsigned int bits)
{
#if __BITS_PER_LONG == 64
/* 64x64-bit multiply is efficient on all 64-bit processors */
return val * GOLDEN_RATIO_64 >> (64 - bits);
#else
/* Hash 64 bits using only 32x32-bit multiply. */
return hash_32((u32)val ^ __hash_32(val >> 32), bits);
#endif
}
static inline u32 hash_ptr(const void *ptr, unsigned int bits)
{
return hash_long((unsigned long)ptr, bits);
}
/* This really should be called fold32_ptr; it does no hashing to speak of. */
static inline u32 hash32_ptr(const void *ptr)
{
unsigned long val = (unsigned long)ptr;
#if __BITS_PER_LONG == 64
val ^= (val >> 32);
#endif
return (u32)val;
}
/*
* Routines for hashing strings of bytes to a 32-bit hash value.
*
* These hash functions are NOT GUARANTEED STABLE between kernel
* versions, architectures, or even repeated boots of the same kernel.
* (E.g. they may depend on boot-time hardware detection or be
* deliberately randomized.)
*
* They are also not intended to be secure against collisions caused by
* malicious inputs; much slower hash functions are required for that.
*
* They are optimized for pathname components, meaning short strings.
* Even if a majority of files have longer names, the dynamic profile of
* pathname components skews short due to short directory names.
* (E.g. /usr/lib/libsesquipedalianism.so.3.141.)
*/
/*
* Version 1: one byte at a time. Example of use:
*
* unsigned long hash = init_name_hash;
* while (*p)
* hash = partial_name_hash(tolower(*p++), hash);
* hash = end_name_hash(hash);
*
* Although this is designed for bytes, fs/hfsplus/unicode.c
* abuses it to hash 16-bit values.
*/
/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */
#define init_name_hash(salt) (unsigned long)(salt)
/* partial hash update function. Assume roughly 4 bits per character */
static inline unsigned long
partial_name_hash(unsigned long c, unsigned long prevhash)
{
return (prevhash + (c << 4) + (c >> 4)) * 11;
}
/*
* Finally: cut down the number of bits to a int value (and try to avoid
* losing bits). This also has the property (wanted by the dcache)
* that the msbits make a good hash table index.
*/
static inline unsigned int end_name_hash(unsigned long hash)
{
return hash_long(hash, 32);
}
/*
* Version 2: One word (32 or 64 bits) at a time.
* If CONFIG_DCACHE_WORD_ACCESS is defined (meaning <asm/word-at-a-time.h>
* exists, which describes major Linux platforms like x86 and ARM), then
* this computes a different hash function much faster.
*
* If not set, this falls back to a wrapper around the preceding.
*/
extern unsigned int __pure hash_string(const void *salt, const char *, unsigned int);
/*
* A hash_len is a u64 with the hash of a string in the low
* half and the length in the high half.
*/
#define hashlen_hash(hashlen) ((u32)(hashlen))
#define hashlen_len(hashlen) ((u32)((hashlen) >> 32))
#define hashlen_create(hash, len) ((u64)(len)<<32 | (u32)(hash))
/* Return the "hash_len" (hash and length) of a null-terminated string */
extern u64 __pure hashlen_string(const void *salt, const char *name);
#endif /* _BR_HASH_H */

View File

@@ -1,202 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* adaptation of Linux kernel's <linux/hashtable.h>
*/
/*
* Statically sized hash table implementation
* (C) 2012 Sasha Levin <levinsasha928@gmail.com>
*/
#ifndef _LINUX_HASHTABLE_H
#define _LINUX_HASHTABLE_H
#include "list.h"
#include "hash.h"
//#include <linux/rculist.h>
#define DEFINE_HASHTABLE(name, bits) \
struct hlist_head name[1 << (bits)] = \
{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
#define DEFINE_READ_MOSTLY_HASHTABLE(name, bits) \
struct hlist_head name[1 << (bits)] __read_mostly = \
{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
#define DECLARE_HASHTABLE(name, bits) \
struct hlist_head name[1 << (bits)]
#define HASH_SIZE(name) (ARRAY_SIZE(name))
#define HASH_BITS(name) ilog2(HASH_SIZE(name))
/* Use hash_32 when possible to allow for fast 32bit hashing in 64bit kernels. */
#define hash_min(val, bits) \
(sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits))
static inline void __hash_init(struct hlist_head *ht, unsigned int sz)
{
unsigned int i;
for (i = 0; i < sz; i++)
INIT_HLIST_HEAD(&ht[i]);
}
/**
* hash_init - initialize a hash table
* @hashtable: hashtable to be initialized
*
* Calculates the size of the hashtable from the given parameter, otherwise
* same as hash_init_size.
*
* This has to be a macro since HASH_BITS() will not work on pointers since
* it calculates the size during preprocessing.
*/
#define hash_init(hashtable) __hash_init(hashtable, HASH_SIZE(hashtable))
/**
* hash_add - add an object to a hashtable
* @hashtable: hashtable to add to
* @node: the &struct hlist_node of the object to be added
* @key: the key of the object to be added
*/
#define hash_add(hashtable, node, key) \
hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
/**
* hash_add_rcu - add an object to a rcu enabled hashtable
* @hashtable: hashtable to add to
* @node: the &struct hlist_node of the object to be added
* @key: the key of the object to be added
*/
#define hash_add_rcu(hashtable, node, key) \
hlist_add_head_rcu(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
/**
* hash_hashed - check whether an object is in any hashtable
* @node: the &struct hlist_node of the object to be checked
*/
static inline bool hash_hashed(struct hlist_node *node)
{
return !hlist_unhashed(node);
}
static inline bool __hash_empty(struct hlist_head *ht, unsigned int sz)
{
unsigned int i;
for (i = 0; i < sz; i++)
if (!hlist_empty(&ht[i]))
return false;
return true;
}
/**
* hash_empty - check whether a hashtable is empty
* @hashtable: hashtable to check
*
* This has to be a macro since HASH_BITS() will not work on pointers since
* it calculates the size during preprocessing.
*/
#define hash_empty(hashtable) __hash_empty(hashtable, HASH_SIZE(hashtable))
/**
* hash_del - remove an object from a hashtable
* @node: &struct hlist_node of the object to remove
*/
static inline void hash_del(struct hlist_node *node)
{
hlist_del_init(node);
}
/**
* hash_for_each - iterate over a hashtable
* @name: hashtable to iterate
* @bkt: integer to use as bucket loop cursor
* @obj: the type * to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
*/
#define hash_for_each(name, bkt, obj, member) \
for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\
(bkt)++)\
hlist_for_each_entry(obj, &name[bkt], member)
/**
* hash_for_each_rcu - iterate over a rcu enabled hashtable
* @name: hashtable to iterate
* @bkt: integer to use as bucket loop cursor
* @obj: the type * to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
*/
#define hash_for_each_rcu(name, bkt, obj, member) \
for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\
(bkt)++)\
hlist_for_each_entry_rcu(obj, &name[bkt], member)
/**
* hash_for_each_safe - iterate over a hashtable safe against removal of
* hash entry
* @name: hashtable to iterate
* @bkt: integer to use as bucket loop cursor
* @tmp: a &struct hlist_node used for temporary storage
* @obj: the type * to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
*/
#define hash_for_each_safe(name, bkt, tmp, obj, member) \
for ((bkt) = 0, obj = NULL; obj == NULL && (bkt) < HASH_SIZE(name);\
(bkt)++)\
hlist_for_each_entry_safe(obj, tmp, &name[bkt], member)
/**
* hash_for_each_possible - iterate over all possible objects hashing to the
* same bucket
* @name: hashtable to iterate
* @obj: the type * to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
* @key: the key of the objects to iterate over
*/
#define hash_for_each_possible(name, obj, member, key) \
hlist_for_each_entry(obj, &name[hash_min(key, HASH_BITS(name))], member)
/**
* hash_for_each_possible_rcu - iterate over all possible objects hashing to the
* same bucket in an rcu enabled hashtable
* @name: hashtable to iterate
* @obj: the type * to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
* @key: the key of the objects to iterate over
*/
#define hash_for_each_possible_rcu(name, obj, member, key, cond...) \
hlist_for_each_entry_rcu(obj, &name[hash_min(key, HASH_BITS(name))],\
member, ## cond)
/**
* hash_for_each_possible_rcu_notrace - iterate over all possible objects hashing
* to the same bucket in an rcu enabled hashtable in a rcu enabled hashtable
* @name: hashtable to iterate
* @obj: the type * to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
* @key: the key of the objects to iterate over
*
* This is the same as hash_for_each_possible_rcu() except that it does
* not do any RCU debugging or tracing.
*/
#define hash_for_each_possible_rcu_notrace(name, obj, member, key) \
hlist_for_each_entry_rcu_notrace(obj, \
&name[hash_min(key, HASH_BITS(name))], member)
/**
* hash_for_each_possible_safe - iterate over all possible objects hashing to the
* same bucket safe against removals
* @name: hashtable to iterate
* @obj: the type * to use as a loop cursor for each entry
* @tmp: a &struct hlist_node used for temporary storage
* @member: the name of the hlist_node within the struct
* @key: the key of the objects to iterate over
*/
#define hash_for_each_possible_safe(name, obj, tmp, member, key) \
hlist_for_each_entry_safe(obj, tmp,\
&name[hash_min(key, HASH_BITS(name))], member)
#endif

View File

@@ -1,18 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* taken from Kernel's <linux/compiler.h
*/
#ifndef __LIKELY_H
#define __LIKELY_H
/* See https://kernelnewbies.org/FAQ/LikelyUnlikely
*
* In 2 words:
* "You should use it [likely() and unlikely()] only in cases when the likeliest
* branch is very very very likely, or when the unlikeliest branch is very very
* very unlikely."
*/
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
#endif /* __LIKELY_H */

View File

@@ -1,992 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* adaptation of kernel's <linux/list.h>
*
*/
#ifndef __BR_LIST_H
#define __BR_LIST_H
#include <stddef.h>
#include <stdbool.h>
#include "rwonce.h"
#include "container-of.h"
/************ originally in <include/linux/types.h> */
struct list_head {
struct list_head *next, *prev;
};
struct hlist_head {
struct hlist_node *first;
};
struct hlist_node {
struct hlist_node *next, **pprev;
};
/************ originally in <include/linux/poison.h> */
# define POISON_POINTER_DELTA 0
/* These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses
* non-initialized list entries.
*/
#define LIST_POISON1 ((void *) 0x100 + POISON_POINTER_DELTA)
#define LIST_POISON2 ((void *) 0x200 + POISON_POINTER_DELTA)
/*
* Circular doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
/**
* INIT_LIST_HEAD - Initialize a list_head structure
* @list: list_head structure to be initialized.
*
* Initializes the list_head to point to itself. If it is a list header,
* the result is an empty list.
*/
static inline void INIT_LIST_HEAD(struct list_head *list)
{
WRITE_ONCE(list->next, list);
list->prev = list;
}
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
WRITE_ONCE(prev->next, new);
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
/*
* Delete a list entry by making the prev/next entries
* point to each other.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
WRITE_ONCE(prev->next, next);
}
/*
* Delete a list entry and clear the 'prev' pointer.
*
* This is a special-purpose list clearing method used in the networking code
* for lists allocated as per-cpu, where we don't want to incur the extra
* WRITE_ONCE() overhead of a regular list_del_init(). The code that uses this
* needs to check the node 'prev' pointer instead of calling list_empty().
*/
static inline void __list_del_clearprev(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->prev = NULL;
}
static inline void __list_del_entry(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}
/**
* list_del - deletes entry from list.
* @entry: the element to delete from the list.
* Note: list_empty() on entry does not return true after this, the entry is
* in an undefined state.
*/
static inline void list_del(struct list_head *entry)
{
__list_del_entry(entry);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
/**
* list_replace - replace old entry by new one
* @old : the element to be replaced
* @new : the new element to insert
*
* If @old was empty, it will be overwritten.
*/
static inline void list_replace(struct list_head *old,
struct list_head *new)
{
new->next = old->next;
new->next->prev = new;
new->prev = old->prev;
new->prev->next = new;
}
/**
* list_replace_init - replace old entry by new one and initialize the old one
* @old : the element to be replaced
* @new : the new element to insert
*
* If @old was empty, it will be overwritten.
*/
static inline void list_replace_init(struct list_head *old,
struct list_head *new)
{
list_replace(old, new);
INIT_LIST_HEAD(old);
}
/**
* list_swap - replace entry1 with entry2 and re-add entry1 at entry2's position
* @entry1: the location to place entry2
* @entry2: the location to place entry1
*/
static inline void list_swap(struct list_head *entry1,
struct list_head *entry2)
{
struct list_head *pos = entry2->prev;
list_del(entry2);
list_replace(entry1, entry2);
if (pos == entry1)
pos = entry2;
list_add(entry1, pos);
}
/**
* list_del_init - deletes entry from list and reinitialize it.
* @entry: the element to delete from the list.
*/
static inline void list_del_init(struct list_head *entry)
{
__list_del_entry(entry);
INIT_LIST_HEAD(entry);
}
/**
* list_move - delete from one list and add as another's head
* @list: the entry to move
* @head: the head that will precede our entry
*/
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del_entry(list);
list_add(list, head);
}
/**
* list_move_tail - delete from one list and add as another's tail
* @list: the entry to move
* @head: the head that will follow our entry
*/
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del_entry(list);
list_add_tail(list, head);
}
/**
* list_bulk_move_tail - move a subsection of a list to its tail
* @head: the head that will follow our entry
* @first: first entry to move
* @last: last entry to move, can be the same as first
*
* Move all entries between @first and including @last before @head.
* All three entries must belong to the same linked list.
*/
static inline void list_bulk_move_tail(struct list_head *head,
struct list_head *first,
struct list_head *last)
{
first->prev->next = last->next;
last->next->prev = first->prev;
head->prev->next = first;
first->prev = head->prev;
last->next = head;
head->prev = last;
}
/**
* list_is_first -- tests whether @list is the first entry in list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_first(const struct list_head *list,
const struct list_head *head)
{
return list->prev == head;
}
/**
* list_is_last - tests whether @list is the last entry in list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_last(const struct list_head *list,
const struct list_head *head)
{
return list->next == head;
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return READ_ONCE(head->next) == head;
}
/**
* list_rotate_left - rotate the list to the left
* @head: the head of the list
*/
static inline void list_rotate_left(struct list_head *head)
{
struct list_head *first;
if (!list_empty(head)) {
first = head->next;
list_move_tail(first, head);
}
}
/**
* list_rotate_to_front() - Rotate list to specific item.
* @list: The desired new front of the list.
* @head: The head of the list.
*
* Rotates list so that @list becomes the new front of the list.
*/
static inline void list_rotate_to_front(struct list_head *list,
struct list_head *head)
{
/*
* Deletes the list head from the list denoted by @head and
* places it as the tail of @list, this effectively rotates the
* list so that @list is at the front.
*/
list_move_tail(head, list);
}
/**
* list_is_singular - tests whether a list has just one entry.
* @head: the list to test.
*/
static inline int list_is_singular(const struct list_head *head)
{
return !list_empty(head) && (head->next == head->prev);
}
static inline void __list_cut_position(struct list_head *list,
struct list_head *head, struct list_head *entry)
{
struct list_head *new_first = entry->next;
list->next = head->next;
list->next->prev = list;
list->prev = entry;
entry->next = list;
head->next = new_first;
new_first->prev = head;
}
/**
* list_cut_position - cut a list into two
* @list: a new list to add all removed entries
* @head: a list with entries
* @entry: an entry within head, could be the head itself
* and if so we won't cut the list
*
* This helper moves the initial part of @head, up to and
* including @entry, from @head to @list. You should
* pass on @entry an element you know is on @head. @list
* should be an empty list or a list you do not care about
* losing its data.
*
*/
static inline void list_cut_position(struct list_head *list,
struct list_head *head, struct list_head *entry)
{
if (list_empty(head))
return;
if (list_is_singular(head) &&
(head->next != entry && head != entry))
return;
if (entry == head)
INIT_LIST_HEAD(list);
else
__list_cut_position(list, head, entry);
}
/**
* list_cut_before - cut a list into two, before given entry
* @list: a new list to add all removed entries
* @head: a list with entries
* @entry: an entry within head, could be the head itself
*
* This helper moves the initial part of @head, up to but
* excluding @entry, from @head to @list. You should pass
* in @entry an element you know is on @head. @list should
* be an empty list or a list you do not care about losing
* its data.
* If @entry == @head, all entries on @head are moved to
* @list.
*/
static inline void list_cut_before(struct list_head *list,
struct list_head *head,
struct list_head *entry)
{
if (head->next == entry) {
INIT_LIST_HEAD(list);
return;
}
list->next = head->next;
list->next->prev = list;
list->prev = entry->prev;
list->prev->next = list;
head->next = entry;
entry->prev = head;
}
static inline void __list_splice(const struct list_head *list,
struct list_head *prev,
struct list_head *next)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
first->prev = prev;
prev->next = first;
last->next = next;
next->prev = last;
}
/**
* list_splice - join two lists, this is designed for stacks
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(const struct list_head *list,
struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head, head->next);
}
/**
* list_splice_tail - join two lists, each list being a queue
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice_tail(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head->prev, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head, head->next);
INIT_LIST_HEAD(list);
}
}
/**
* list_splice_tail_init - join two lists and reinitialise the emptied list
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* Each of the lists is a queue.
* The list at @list is reinitialised
*/
static inline void list_splice_tail_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head->prev, head);
INIT_LIST_HEAD(list);
}
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_last_entry - get the last element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_last_entry(ptr, type, member) \
list_entry((ptr)->prev, type, member)
/**
* list_first_entry_or_null - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*
* Note that if the list is empty, it returns NULL.
*/
#define list_first_entry_or_null(ptr, type, member) ({ \
struct list_head *head__ = (ptr); \
struct list_head *pos__ = READ_ONCE(head__->next); \
pos__ != head__ ? list_entry(pos__, type, member) : NULL; \
})
/**
* list_next_entry - get the next element in list
* @pos: the type * to cursor
* @member: the name of the list_head within the struct.
*/
#define list_next_entry(pos, member) \
list_entry((pos)->member.next, __typeof__(*(pos)), member)
/**
* list_prev_entry - get the prev element in list
* @pos: the type * to cursor
* @member: the name of the list_head within the struct.
*/
#define list_prev_entry(pos, member) \
list_entry((pos)->member.prev, __typeof__(*(pos)), member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* list_for_each_continue - continue iteration over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*
* Continue to iterate over a list, continuing after the current position.
*/
#define list_for_each_continue(pos, head) \
for (pos = pos->next; pos != (head); pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
#define list_for_each_prev_safe(pos, n, head) \
for (pos = (head)->prev, n = pos->prev; \
pos != (head); \
pos = n, n = pos->prev)
/**
* list_entry_is_head - test if the entry points to the head of the list
* @pos: the type * to cursor
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_entry_is_head(pos, head, member) \
(&pos->member == (head))
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry(head, __typeof__(*pos), member); \
!list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_last_entry(head, __typeof__(*pos), member); \
!list_entry_is_head(pos, head, member); \
pos = list_prev_entry(pos, member))
/**
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
* @pos: the type * to use as a start point
* @head: the head of the list
* @member: the name of the list_head within the struct.
*
* Prepares a pos entry for use as a start point in list_for_each_entry_continue().
*/
#define list_prepare_entry(pos, head, member) \
((pos) ? : list_entry(head, __typeof__(*pos), member))
/**
* list_for_each_entry_continue - continue iteration over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*
* Continue to iterate over list of given type, continuing after
* the current position.
*/
#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_next_entry(pos, member); \
!list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member))
/**
* list_for_each_entry_continue_reverse - iterate backwards from the given point
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*
* Start to iterate over list of given type backwards, continuing after
* the current position.
*/
#define list_for_each_entry_continue_reverse(pos, head, member) \
for (pos = list_prev_entry(pos, member); \
!list_entry_is_head(pos, head, member); \
pos = list_prev_entry(pos, member))
/**
* list_for_each_entry_from - iterate over list of given type from the current point
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*
* Iterate over list of given type, continuing from current position.
*/
#define list_for_each_entry_from(pos, head, member) \
for (; !list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member))
/**
* list_for_each_entry_from_reverse - iterate backwards over list of given type
* from the current point
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*
* Iterate backwards over list of given type, continuing from current position.
*/
#define list_for_each_entry_from_reverse(pos, head, member) \
for (; !list_entry_is_head(pos, head, member); \
pos = list_prev_entry(pos, member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_first_entry(head, __typeof__(*pos), member), \
n = list_next_entry(pos, member); \
!list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member))
/**
* list_for_each_entry_safe_continue - continue list iteration safe against removal
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*
* Iterate over list of given type, continuing after current point,
* safe against removal of list entry.
*/
#define list_for_each_entry_safe_continue(pos, n, head, member) \
for (pos = list_next_entry(pos, member), \
n = list_next_entry(pos, member); \
!list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member))
/**
* list_for_each_entry_safe_from - iterate over list from current point safe against removal
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*
* Iterate over list of given type from current point, safe against
* removal of list entry.
*/
#define list_for_each_entry_safe_from(pos, n, head, member) \
for (n = list_next_entry(pos, member); \
!list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member))
/**
* list_for_each_entry_safe_reverse - iterate backwards over list safe against removal
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*
* Iterate backwards over list of given type, safe against removal
* of list entry.
*/
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_last_entry(head, __typeof__(*pos), member), \
n = list_prev_entry(pos, member); \
!list_entry_is_head(pos, head, member); \
pos = n, n = list_prev_entry(n, member))
/**
* list_safe_reset_next - reset a stale list_for_each_entry_safe loop
* @pos: the loop cursor used in the list_for_each_entry_safe loop
* @n: temporary storage used in list_for_each_entry_safe
* @member: the name of the list_head within the struct.
*
* list_safe_reset_next is not safe to use in general if the list may be
* modified concurrently (eg. the lock is dropped in the loop body). An
* exception to this is if the cursor element (pos) is pinned in the list,
* and list_safe_reset_next is called after re-taking the lock and before
* completing the current iteration of the loop body.
*/
#define list_safe_reset_next(pos, n, member) \
n = list_next_entry(pos, member)
/*
* Double linked lists with a single pointer list head.
* Mostly useful for hash tables where the two pointer list head is
* too wasteful.
* You lose the ability to access the tail in O(1).
*/
#define HLIST_HEAD_INIT { .first = NULL }
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
static inline void INIT_HLIST_NODE(struct hlist_node *h)
{
h->next = NULL;
h->pprev = NULL;
}
/**
* hlist_unhashed - Has node been removed from list and reinitialized?
* @h: Node to be checked
*
* Not that not all removal functions will leave a node in unhashed
* state. For example, hlist_nulls_del_init_rcu() does leave the
* node in unhashed state, but hlist_nulls_del() does not.
*/
static inline int hlist_unhashed(const struct hlist_node *h)
{
return !h->pprev;
}
/**
* hlist_unhashed_lockless - Version of hlist_unhashed for lockless use
* @h: Node to be checked
*
* This variant of hlist_unhashed() must be used in lockless contexts
* to avoid potential load-tearing. The READ_ONCE() is paired with the
* various WRITE_ONCE() in hlist helpers that are defined below.
*/
static inline int hlist_unhashed_lockless(const struct hlist_node *h)
{
return !READ_ONCE(h->pprev);
}
/**
* hlist_empty - Is the specified hlist_head structure an empty hlist?
* @h: Structure to check.
*/
static inline int hlist_empty(const struct hlist_head *h)
{
return !READ_ONCE(h->first);
}
static inline void __hlist_del(struct hlist_node *n)
{
struct hlist_node *next = n->next;
struct hlist_node **pprev = n->pprev;
WRITE_ONCE(*pprev, next);
if (next)
WRITE_ONCE(next->pprev, pprev);
}
/**
* hlist_del - Delete the specified hlist_node from its list
* @n: Node to delete.
*
* Note that this function leaves the node in hashed state. Use
* hlist_del_init() or similar instead to unhash @n.
*/
static inline void hlist_del(struct hlist_node *n)
{
__hlist_del(n);
n->next = LIST_POISON1;
n->pprev = LIST_POISON2;
}
/**
* hlist_del_init - Delete the specified hlist_node from its list and initialize
* @n: Node to delete.
*
* Note that this function leaves the node in unhashed state.
*/
static inline void hlist_del_init(struct hlist_node *n)
{
if (!hlist_unhashed(n)) {
__hlist_del(n);
INIT_HLIST_NODE(n);
}
}
/**
* hlist_add_head - add a new entry at the beginning of the hlist
* @n: new entry to be added
* @h: hlist head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
struct hlist_node *first = h->first;
WRITE_ONCE(n->next, first);
if (first)
WRITE_ONCE(first->pprev, &n->next);
WRITE_ONCE(h->first, n);
WRITE_ONCE(n->pprev, &h->first);
}
/**
* hlist_add_before - add a new entry before the one specified
* @n: new entry to be added
* @next: hlist node to add it before, which must be non-NULL
*/
static inline void hlist_add_before(struct hlist_node *n,
struct hlist_node *next)
{
WRITE_ONCE(n->pprev, next->pprev);
WRITE_ONCE(n->next, next);
WRITE_ONCE(next->pprev, &n->next);
WRITE_ONCE(*(n->pprev), n);
}
/**
* hlist_add_behind - add a new entry after the one specified
* @n: new entry to be added
* @prev: hlist node to add it after, which must be non-NULL
*/
static inline void hlist_add_behind(struct hlist_node *n,
struct hlist_node *prev)
{
WRITE_ONCE(n->next, prev->next);
WRITE_ONCE(prev->next, n);
WRITE_ONCE(n->pprev, &prev->next);
if (n->next)
WRITE_ONCE(n->next->pprev, &n->next);
}
/**
* hlist_add_fake - create a fake hlist consisting of a single headless node
* @n: Node to make a fake list out of
*
* This makes @n appear to be its own predecessor on a headless hlist.
* The point of this is to allow things like hlist_del() to work correctly
* in cases where there is no list.
*/
static inline void hlist_add_fake(struct hlist_node *n)
{
n->pprev = &n->next;
}
/**
* hlist_fake: Is this node a fake hlist?
* @h: Node to check for being a self-referential fake hlist.
*/
static inline bool hlist_fake(struct hlist_node *h)
{
return h->pprev == &h->next;
}
/**
* hlist_is_singular_node - is node the only element of the specified hlist?
* @n: Node to check for singularity.
* @h: Header for potentially singular list.
*
* Check whether the node is the only node of the head without
* accessing head, thus avoiding unnecessary cache misses.
*/
static inline bool
hlist_is_singular_node(struct hlist_node *n, struct hlist_head *h)
{
return !n->next && n->pprev == &h->first;
}
/**
* hlist_move_list - Move an hlist
* @old: hlist_head for old list.
* @new: hlist_head for new list.
*
* Move a list from one list head to another. Fixup the pprev
* reference of the first entry if it exists.
*/
static inline void hlist_move_list(struct hlist_head *old,
struct hlist_head *new)
{
new->first = old->first;
if (new->first)
new->first->pprev = &new->first;
old->first = NULL;
}
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
#define hlist_for_each(pos, head) \
for (pos = (head)->first; pos ; pos = pos->next)
#define hlist_for_each_safe(pos, n, head) \
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
pos = n)
#define hlist_entry_safe(ptr, type, member) \
({ __typeof__(ptr) ____ptr = (ptr); \
____ptr ? hlist_entry(____ptr, type, member) : NULL; \
})
/**
* hlist_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry(pos, head, member) \
for (pos = hlist_entry_safe((head)->first, __typeof__(*(pos)), member); \
pos; \
pos = hlist_entry_safe((pos)->member.next, __typeof__(*(pos)), member))
/**
* hlist_for_each_entry_continue - iterate over a hlist continuing after current point
* @pos: the type * to use as a loop cursor.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_continue(pos, member) \
for (pos = hlist_entry_safe((pos)->member.next, __typeof__(*(pos)), member); \
pos; \
pos = hlist_entry_safe((pos)->member.next, __typeof__(*(pos)), member))
/**
* hlist_for_each_entry_from - iterate over a hlist continuing from current point
* @pos: the type * to use as a loop cursor.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_from(pos, member) \
for (; pos; \
pos = hlist_entry_safe((pos)->member.next, __typeof__(*(pos)), member))
/**
* hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: a &struct hlist_node to use as temporary storage
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry_safe(pos, n, head, member) \
for (pos = hlist_entry_safe((head)->first, __typeof__(*pos), member); \
pos && ({ n = pos->member.next; 1; }); \
pos = hlist_entry_safe(n, __typeof__(*pos), member))
#endif /* __BR_LIST_H */

View File

@@ -1,53 +0,0 @@
/* pjwhash-inline.h - PJW hash function, inline version.
*
* Copyright (C) 2021-2022 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#ifndef _PJWHASH_INLINE_H
#define _PJWHASH_INLINE_H
#include "bits.h"
#define THREE_QUARTERS ((int) ((BITS_PER_INT * 3) / 4))
#define ONE_EIGHTH ((int) (BITS_PER_INT / 8))
#define HIGH_BITS ( ~((uint)(~0) >> ONE_EIGHTH ))
#ifndef _pjw_inline
#define _pjw_inline static inline
#endif
/**
* unsigned int pjwhash - PJW hash function
* @key: the key address.
* @length: the length of key.
*
* This hash was created by Peter Jay Weinberger (AT&T Bell Labs):
* https://en.wikipedia.org/wiki/PJW_hash_function
*
* Return: the PJW hash.
*/
_pjw_inline uint pjwhash(const void* key, uint length)
{
uint hash = 0, high;
const u8 *k = key;
for (uint i = 0; i < length; ++k, ++i) {
hash = (hash << ONE_EIGHTH) + *k;
high = hash & HIGH_BITS;
if (high != 0) {
hash ^= high >> THREE_QUARTERS;
hash &= ~high;
}
}
return hash;
}
#endif /* _PJWHASH_INLINE_H */

View File

@@ -1,30 +0,0 @@
/* pjwhash.h - PJW hash function, extern version.
*
* Copyright (C) 2021-2022 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*/
#ifndef _PJWHASH_H
#define _PJWHASH_H
#include "bits.h"
/**
* unsigned int pjwhash - PJW hash function
* @key: the key address.
* @length: the length of key.
*
* This hash was created by Peter Jay Weinberger (AT&T Bell Labs):
* https://en.wikipedia.org/wiki/PJW_hash_function
*
* Return: the PJW hash.
*/
extern uint pjwhash (const void* key, uint length);
#endif /* _PJWHASH_H */

View File

@@ -1,345 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* adaptation of kernel's <linux/plist.h>
*
*/
/*
* Descending-priority-sorted double-linked list
*
* (C) 2002-2003 Intel Corp
* Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>.
*
* 2001-2005 (c) MontaVista Software, Inc.
* Daniel Walker <dwalker@mvista.com>
*
* (C) 2005 Thomas Gleixner <tglx@linutronix.de>
*
* Simplifications of the original code by
* Oleg Nesterov <oleg@tv-sign.ru>
*
* Based on simple lists (include/linux/list.h).
*
* This is a priority-sorted list of nodes; each node has a
* priority from INT_MIN (highest) to INT_MAX (lowest).
*
* Addition is O(K), removal is O(1), change of priority of a node is
* O(K) and K is the number of RT priority levels used in the system.
* (1 <= K <= 99)
*
* This list is really a list of lists:
*
* - The tier 1 list is the prio_list, different priority nodes.
*
* - The tier 2 list is the node_list, serialized nodes.
*
* Simple ASCII art explanation:
*
* pl:prio_list (only for plist_node)
* nl:node_list
* HEAD| NODE(S)
* |
* ||------------------------------------|
* ||->|pl|<->|pl|<--------------->|pl|<-|
* | |10| |21| |21| |21| |40| (prio)
* | | | | | | | | | | |
* | | | | | | | | | | |
* |->|nl|<->|nl|<->|nl|<->|nl|<->|nl|<->|nl|<-|
* |-------------------------------------------|
*
* The nodes on the prio_list list are sorted by priority to simplify
* the insertion of new nodes. There are no nodes with duplicate
* priorites on the list.
*
* The nodes on the node_list are ordered by priority and can contain
* entries which have the same priority. Those entries are ordered
* FIFO
*
* Addition means: look for the prio_list node in the prio_list
* for the priority of the node and insert it before the node_list
* entry of the next prio_list node. If it is the first node of
* that priority, add it to the prio_list in the right position and
* insert it into the serialized node_list list
*
* Removal means remove it from the node_list and remove it from
* the prio_list if the node_list list_head is non empty. In case
* of removal from the prio_list it must be checked whether other
* entries of the same priority are on the list or not. If there
* is another entry of the same priority then this entry has to
* replace the removed entry on the prio_list. If the entry which
* is removed is the only entry of this priority then a simple
* remove from both list is sufficient.
*
* INT_MIN is the highest priority, 0 is the medium highest, INT_MAX
* is lowest priority.
*
* No locking is done, up to the caller.
*/
#ifndef _LINUX_PLIST_H_
#define _LINUX_PLIST_H_
#include "container-of.h"
#include "list.h"
//#include <types.h>
// #include <asm/bug.h>
struct plist_head {
struct list_head node_list;
};
struct plist_node {
int prio;
struct list_head prio_list;
struct list_head node_list;
};
/**
* PLIST_HEAD_INIT - static struct plist_head initializer
* @head: struct plist_head variable name
*/
#define PLIST_HEAD_INIT(head) \
{ \
.node_list = LIST_HEAD_INIT((head).node_list) \
}
/**
* PLIST_HEAD - declare and init plist_head
* @head: name for struct plist_head variable
*/
#define PLIST_HEAD(head) \
struct plist_head head = PLIST_HEAD_INIT(head)
/**
* PLIST_NODE_INIT - static struct plist_node initializer
* @node: struct plist_node variable name
* @__prio: initial node priority
*/
#define PLIST_NODE_INIT(node, __prio) \
{ \
.prio = (__prio), \
.prio_list = LIST_HEAD_INIT((node).prio_list), \
.node_list = LIST_HEAD_INIT((node).node_list), \
}
/**
* plist_head_init - dynamic struct plist_head initializer
* @head: &struct plist_head pointer
*/
static inline void
plist_head_init(struct plist_head *head)
{
INIT_LIST_HEAD(&head->node_list);
}
/**
* plist_node_init - Dynamic struct plist_node initializer
* @node: &struct plist_node pointer
* @prio: initial node priority
*/
static inline void plist_node_init(struct plist_node *node, int prio)
{
node->prio = prio;
INIT_LIST_HEAD(&node->prio_list);
INIT_LIST_HEAD(&node->node_list);
}
extern void plist_add(struct plist_node *node, struct plist_head *head);
extern void plist_del(struct plist_node *node, struct plist_head *head);
extern void plist_requeue(struct plist_node *node, struct plist_head *head);
/**
* plist_for_each - iterate over the plist
* @pos: the type * to use as a loop counter
* @head: the head for your list
*/
#define plist_for_each(pos, head) \
list_for_each_entry(pos, &(head)->node_list, node_list)
/**
* plist_for_each_reverse - iterate backwards over the plist
* @pos: the type * to use as a loop counter
* @head: the head for your list
*/
#define plist_for_each_reverse(pos, head) \
list_for_each_entry_reverse(pos, &(head)->node_list, node_list)
/**
* plist_for_each_continue - continue iteration over the plist
* @pos: the type * to use as a loop cursor
* @head: the head for your list
*
* Continue to iterate over plist, continuing after the current position.
*/
#define plist_for_each_continue(pos, head) \
list_for_each_entry_continue(pos, &(head)->node_list, node_list)
/**
* plist_for_each_continue_reverse - continue iteration over the plist
* @pos: the type * to use as a loop cursor
* @head: the head for your list
*
* Continue to iterate backwards over plist, continuing after the current
* position.
*/
#define plist_for_each_continue_reverse(pos, head) \
list_for_each_entry_continue_reverse(pos, &(head)->node_list, node_list)
/**
* plist_for_each_safe - iterate safely over a plist of given type
* @pos: the type * to use as a loop counter
* @n: another type * to use as temporary storage
* @head: the head for your list
*
* Iterate over a plist of given type, safe against removal of list entry.
*/
#define plist_for_each_safe(pos, n, head) \
list_for_each_entry_safe(pos, n, &(head)->node_list, node_list)
/**
* plist_for_each_safe_reverse - iterate backwards safely over a plist of given type
* @pos: the type * to use as a loop counter
* @n: another type * to use as temporary storage
* @head: the head for your list
*
* Iterate backwards over a plist of given type, safe against removal of list entry.
*/
#define plist_for_each_safe_reverse(pos, n, head) \
list_for_each_entry_safe_reverse(pos, n, &(head)->node_list, node_list)
/**
* plist_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter
* @head: the head for your list
* @mem: the name of the list_head within the struct
*/
#define plist_for_each_entry(pos, head, mem) \
list_for_each_entry(pos, &(head)->node_list, mem.node_list)
/**
* plist_for_each_entry_reverse - iterate backwards over list of given type
* @pos: the type * to use as a loop counter
* @head: the head for your list
* @mem: the name of the list_head within the struct
*/
#define plist_for_each_entry_reverse(pos, head, mem) \
list_for_each_entry_reverse(pos, &(head)->node_list, mem.node_list)
/**
* plist_for_each_entry_continue - continue iteration over list of given type
* @pos: the type * to use as a loop cursor
* @head: the head for your list
* @m: the name of the list_head within the struct
*
* Continue to iterate over list of given type, continuing after
* the current position.
*/
#define plist_for_each_entry_continue(pos, head, m) \
list_for_each_entry_continue(pos, &(head)->node_list, m.node_list)
/**
* plist_for_each_entry_safe - iterate safely over list of given type
* @pos: the type * to use as a loop counter
* @n: another type * to use as temporary storage
* @head: the head for your list
* @m: the name of the list_head within the struct
*
* Iterate over list of given type, safe against removal of list entry.
*/
#define plist_for_each_entry_safe(pos, n, head, m) \
list_for_each_entry_safe(pos, n, &(head)->node_list, m.node_list)
/**
* plist_head_empty - return !0 if a plist_head is empty
* @head: &struct plist_head pointer
*/
static inline int plist_head_empty(const struct plist_head *head)
{
return list_empty(&head->node_list);
}
/**
* plist_node_empty - return !0 if plist_node is not on a list
* @node: &struct plist_node pointer
*/
static inline int plist_node_empty(const struct plist_node *node)
{
return list_empty(&node->node_list);
}
/* All functions below assume the plist_head is not empty. */
/**
* plist_first_entry - get the struct for the first entry
* @head: the &struct plist_head pointer
* @type: the type of the struct this is embedded in
* @member: the name of the list_head within the struct
*/
#ifdef CONFIG_DEBUG_PLIST
# define plist_first_entry(head, type, member) \
({ \
WARN_ON(plist_head_empty(head)); \
container_of(plist_first(head), type, member); \
})
#else
# define plist_first_entry(head, type, member) \
container_of(plist_first(head), type, member)
#endif
/**
* plist_last_entry - get the struct for the last entry
* @head: the &struct plist_head pointer
* @type: the type of the struct this is embedded in
* @member: the name of the list_head within the struct
*/
#ifdef CONFIG_DEBUG_PLIST
# define plist_last_entry(head, type, member) \
({ \
WARN_ON(plist_head_empty(head)); \
container_of(plist_last(head), type, member); \
})
#else
# define plist_last_entry(head, type, member) \
container_of(plist_last(head), type, member)
#endif
/**
* plist_next - get the next entry in list
* @pos: the type * to cursor
*/
#define plist_next(pos) \
list_next_entry(pos, node_list)
/**
* plist_prev - get the prev entry in list
* @pos: the type * to cursor
*/
#define plist_prev(pos) \
list_prev_entry(pos, node_list)
/**
* plist_first - return the first node (and thus, highest priority)
* @head: the &struct plist_head pointer
*
* Assumes the plist is _not_ empty.
*/
static inline struct plist_node *plist_first(const struct plist_head *head)
{
return list_entry(head->node_list.next,
struct plist_node, node_list);
}
/**
* plist_last - return the last node (and thus, lowest priority)
* @head: the &struct plist_head pointer
*
* Assumes the plist is _not_ empty.
*/
static inline struct plist_node *plist_last(const struct plist_head *head)
{
return list_entry(head->node_list.prev,
struct plist_node, node_list);
}
#endif

View File

@@ -1,90 +0,0 @@
/* pool.h - A simple memory pool manager.
*
* Copyright (C) 2021-2022 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#ifndef POOL_H
#define POOL_H
#include <stdint.h>
#include <stddef.h>
#include "list.h"
#include "bits.h"
#define POOL_NAME_LENGTH (16) /* max name length including trailing \0 */
typedef struct {
struct list_head list_blocks; /* list of allocated blocks in pool */
char data[]; /* objects block */
} block_t;
typedef struct {
char name[POOL_NAME_LENGTH]; /* pool name */
size_t eltsize; /* object size */
u32 available; /* current available elements */
u32 allocated; /* total objects allocated */
u32 growsize; /* number of objects per block allocated */
u32 nblocks; /* number of blocks allocated */
struct list_head list_available; /* available nodes */
struct list_head list_blocks; /* allocated blocks */
} pool_t;
/**
* pool_stats - display some pool statistics
* @pool: the pool address.
*/
void pool_stats(pool_t *pool);
/**
* pool_create - create a new memory pool
* @name: the name to give to the pool.
* @grow: the number of elements to add when no more available.
* @size: the size of an element in pool.
*
* The name will be truncated to 16 characters (including the final '\0').
*
* Return: The address of the created pool, or NULL if error.
*/
pool_t *pool_create(const char *name, u32 grow, size_t size);
/**
* pool_get() - Get an element from a pool.
* @pool: The pool address.
*
* Get an object from the pool.
*
* Return: The address of the object, or NULL if error.
*/
void *pool_get(pool_t *pool);
/**
* pool_add() - Add (free) an element to a pool.
* @pool: The pool address.
* @elt: The address of the object to add to the pool.
*
* The object will be available for further pool_get().
*
* Return: The current number of available elements in pool (including
* @elt).
*/
u32 pool_add(pool_t *pool, void *elt);
/**
* pool_destroy() - destroy a pool.
* @pool: The pool address.
*
* Attention: All memory is freed, but no check is done whether all pool
* elements have been released. Referencing any pool object after this call
* will likely imply some memory corruption.
*/
void pool_destroy(pool_t *pool);
#endif

View File

@@ -1,128 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* adaptation of kernel's <asm-generic/rwonce.h>
* See https://www.kernel.org/doc/Documentation/memory-barriers.txt
*/
/*
* Prevent the compiler from merging or refetching reads or writes. The
* compiler is also forbidden from reordering successive instances of
* READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some
* particular ordering. One way to make the compiler aware of ordering is to
* put the two invocations of READ_ONCE or WRITE_ONCE in different C
* statements.
*
* These two macros will also work on aggregate data types like structs or
* unions.
*
* Their two major use cases are: (1) Mediating communication between
* process-level code and irq/NMI handlers, all running on the same CPU,
* and (2) Ensuring that the compiler does not fold, spindle, or otherwise
* mutilate accesses that either do not require ordering or that interact
* with an explicit memory barrier or atomic instruction that provides the
* required ordering.
*/
#ifndef __BR_RWONCE_H
#define __BR_RWONCE_H
/************ originally in <include/linux/compiler_attributes.h> */
#if __has_attribute(__error__)
# define __compiletime_error(msg) __attribute__((__error__(msg)))
#else
# define __compiletime_error(msg)
#endif
/************ originally in <include/linux/compiler_types.h> */
/*
* __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving
* non-scalar types unchanged.
*/
/*
* Prefer C11 _Generic for better compile-times and simpler code. Note: 'char'
* is not type-compatible with 'signed char', and we define a separate case.
*/
#define __scalar_type_to_expr_cases(type) \
unsigned type: (unsigned type)0, \
signed type: (signed type)0
#define __unqual_scalar_typeof(x) \
typeof(_Generic((x), \
char: (char)0, \
__scalar_type_to_expr_cases(char), \
__scalar_type_to_expr_cases(short), \
__scalar_type_to_expr_cases(int), \
__scalar_type_to_expr_cases(long), \
__scalar_type_to_expr_cases(long long), \
default: (x)))
/* Is this type a native word size -- useful for atomic operations */
#define __native_word(t) \
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
#ifdef __OPTIMIZE__
# define __compiletime_assert(condition, msg, prefix, suffix) \
do { \
extern void prefix ## suffix(void) __compiletime_error(msg); \
if (!(condition)) \
prefix ## suffix(); \
} while (0)
#else
# define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0)
#endif
#define _compiletime_assert(condition, msg, prefix, suffix) \
__compiletime_assert(condition, msg, prefix, suffix)
/**
* compiletime_assert - break build and emit msg if condition is false
* @condition: a compile-time constant condition to check
* @msg: a message to emit if condition is false
*
* In tradition of POSIX assert, this macro will break the build if the
* supplied condition is *false*, emitting the supplied error message if the
* compiler has support to do so.
*/
#define compiletime_assert(condition, msg) \
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
#define compiletime_assert_atomic_type(t) \
compiletime_assert(__native_word(t), \
"Need native word sized stores/loads for atomicity.")
/************ originally in <asm-generic/rwonce.h> */
/*
* Yes, this permits 64-bit accesses on 32-bit architectures. These will
* actually be atomic in some cases (namely Armv7 + LPAE), but for others we
* rely on the access being split into 2x32-bit accesses for a 32-bit quantity
* (e.g. a virtual address) and a strong prevailing wind.
*/
#define compiletime_assert_rwonce_type(t) \
compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \
"Unsupported access size for {READ,WRITE}_ONCE().")
/*
* Use __READ_ONCE() instead of READ_ONCE() if you do not require any
* atomicity. Note that this may result in tears!
*/
#ifndef __READ_ONCE
#define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x))
#endif
#define READ_ONCE(x) \
({ \
compiletime_assert_rwonce_type(x); \
__READ_ONCE(x); \
})
#define __WRITE_ONCE(x, val) \
do { \
*(volatile typeof(x) *)&(x) = (val); \
} while (0)
#define WRITE_ONCE(x, val) \
do { \
compiletime_assert_rwonce_type(x); \
__WRITE_ONCE(x, val); \
} while (0)
#endif /* __BR_RWONCE_H */

View File

@@ -1,79 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_STRINGHASH_H
#define __LINUX_STRINGHASH_H
#include <linux/compiler.h> /* For __pure */
#include <linux/types.h> /* For u32, u64 */
#include <linux/hash.h>
/*
* Routines for hashing strings of bytes to a 32-bit hash value.
*
* These hash functions are NOT GUARANTEED STABLE between kernel
* versions, architectures, or even repeated boots of the same kernel.
* (E.g. they may depend on boot-time hardware detection or be
* deliberately randomized.)
*
* They are also not intended to be secure against collisions caused by
* malicious inputs; much slower hash functions are required for that.
*
* They are optimized for pathname components, meaning short strings.
* Even if a majority of files have longer names, the dynamic profile of
* pathname components skews short due to short directory names.
* (E.g. /usr/lib/libsesquipedalianism.so.3.141.)
*/
/*
* Version 1: one byte at a time. Example of use:
*
* unsigned long hash = init_name_hash;
* while (*p)
* hash = partial_name_hash(tolower(*p++), hash);
* hash = end_name_hash(hash);
*
* Although this is designed for bytes, fs/hfsplus/unicode.c
* abuses it to hash 16-bit values.
*/
/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */
#define init_name_hash(salt) (unsigned long)(salt)
/* partial hash update function. Assume roughly 4 bits per character */
static inline unsigned long
partial_name_hash(unsigned long c, unsigned long prevhash)
{
return (prevhash + (c << 4) + (c >> 4)) * 11;
}
/*
* Finally: cut down the number of bits to a int value (and try to avoid
* losing bits). This also has the property (wanted by the dcache)
* that the msbits make a good hash table index.
*/
static inline unsigned int end_name_hash(unsigned long hash)
{
return hash_long(hash, 32);
}
/*
* Version 2: One word (32 or 64 bits) at a time.
* If CONFIG_DCACHE_WORD_ACCESS is defined (meaning <asm/word-at-a-time.h>
* exists, which describes major Linux platforms like x86 and ARM), then
* this computes a different hash function much faster.
*
* If not set, this falls back to a wrapper around the preceding.
*/
extern unsigned int __pure full_name_hash(const void *salt, const char *, unsigned int);
/*
* A hash_len is a u64 with the hash of a string in the low
* half and the length in the high half.
*/
#define hashlen_hash(hashlen) ((u32)(hashlen))
#define hashlen_len(hashlen) ((u32)((hashlen) >> 32))
#define hashlen_create(hash, len) ((u64)(len)<<32 | (u32)(hash))
/* Return the "hash_len" (hash and length) of a null-terminated string */
extern u64 __pure hashlen_string(const void *salt, const char *name);
#endif /* __LINUX_STRINGHASH_H */

View File

@@ -1,105 +0,0 @@
/* struct-group.h - mirrored structure macros.
*
* Copyright (C) 2021-2022 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
* Some parts are taken from Linux's kernel <linux/stddef.h> and others, and are :
* SPDX-License-Identifier: GPL-2.0
*
*/
#ifndef _STRUCT_GROUP_H
#define _STRUCT_GROUP_H
/**
* __struct_group() - Create a mirrored named and anonyomous struct
*
* @TAG: The tag name for the named sub-struct (usually empty)
* @NAME: The identifier name of the mirrored sub-struct
* @ATTRS: Any struct attributes (usually empty)
* @MEMBERS: The member declarations for the mirrored structs
*
* Used to create an anonymous union of two structs with identical layout
* and size: one anonymous and one named. The former's members can be used
* normally without sub-struct naming, and the latter can be used to
* reason about the start, end, and size of the group of struct members.
* The named struct can also be explicitly tagged for layer reuse, as well
* as both having struct attributes appended.
*/
#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \
union { \
struct { MEMBERS } ATTRS; \
struct TAG { MEMBERS } ATTRS NAME; \
}
/**
* DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union
*
* @TYPE: The type of each flexible array element
* @NAME: The name of the flexible array member
*
* In order to have a flexible array member in a union or alone in a
* struct, it needs to be wrapped in an anonymous struct with at least 1
* named member, but that member can be empty.
*/
#define DECLARE_FLEX_ARRAY(TYPE, NAME) \
struct { \
struct { } __empty_ ## NAME; \
TYPE NAME[]; \
}
/**
* struct_group() - Wrap a set of declarations in a mirrored struct
*
* @NAME: The identifier name of the mirrored sub-struct
* @MEMBERS: The member declarations for the mirrored structs
*
* Used to create an anonymous union of two structs with identical
* layout and size: one anonymous and one named. The former can be
* used normally without sub-struct naming, and the latter can be
* used to reason about the start, end, and size of the group of
* struct members.
*/
#define struct_group(NAME, MEMBERS...) \
__struct_group(/* no tag */, NAME, /* no attrs */, MEMBERS)
/**
* struct_group_attr() - Create a struct_group() with trailing attributes
*
* @NAME: The identifier name of the mirrored sub-struct
* @ATTRS: Any struct attributes to apply
* @MEMBERS: The member declarations for the mirrored structs
*
* Used to create an anonymous union of two structs with identical
* layout and size: one anonymous and one named. The former can be
* used normally without sub-struct naming, and the latter can be
* used to reason about the start, end, and size of the group of
* struct members. Includes structure attributes argument.
*/
#define struct_group_attr(NAME, ATTRS, MEMBERS...) \
__struct_group(/* no tag */, NAME, ATTRS, MEMBERS)
/**
* struct_group_tagged() - Create a struct_group with a reusable tag
*
* @TAG: The tag name for the named sub-struct
* @NAME: The identifier name of the mirrored sub-struct
* @MEMBERS: The member declarations for the mirrored structs
*
* Used to create an anonymous union of two structs with identical
* layout and size: one anonymous and one named. The former can be
* used normally without sub-struct naming, and the latter can be
* used to reason about the start, end, and size of the group of
* struct members. Includes struct tag argument for the named copy,
* so the specified layout can be reused later.
*/
#define struct_group_tagged(TAG, NAME, MEMBERS...) \
__struct_group(TAG, NAME, /* no attrs */, MEMBERS)
#endif /* _STRUCT_GROUP_H */

View File

@@ -1,91 +0,0 @@
/* bits.c - information about bitops implementation.
*
* Copyright (C) 2021-2022 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#include "bits.h"
#include "debug.h"
/**
* bits_implementation - display bitops implementation.
*
* For basic bitops (popcount, ctz, etc...), print the implementation
* (builtin, emulated).
*/
void bits_implementation(void)
{
log(0, "bitops implementation: ");
log(0, "popcount64: ");
# if __has_builtin(__builtin_popcountl)
log(0, "builtin, ");
# else
log(0, "emulated, ");
# endif
log(0, "popcount32: ");
# if __has_builtin(__builtin_popcount)
log(0, "builtin, ");
# else
log(0, "emulated, ");
# endif
log(0, "ctz64: ");
# if __has_builtin(__builtin_ctzl)
log(0, "builtin, ");
# elif __has_builtin(__builtin_clzl)
log(0, "builtin (clzl), ");
# else
log(0, "emulated, ");
# endif
log(0, "ctz32: ");
# if __has_builtin(__builtin_ctz)
log(0, "builtin, ");
# elif __has_builtin(__builtin_clz)
log(0, "builtin (clz), ");
# else
log(0, "emulated, ");
# endif
log(0, "clz64: ");
# if __has_builtin(__builtin_clzl)
log(0, "builtin, ");
# else
log(0, "emulated, ");
# endif
log(0, "clz32: ");
# if __has_builtin(__builtin_clz)
log(0, "builtin, ");
# else
log(0, "emulated, ");
# endif
log(0, "ffs64: ");
# if __has_builtin(__builtin_ffsl)
log(0, "builtin, ");
# elif __has_builtin(__builtin_ctzl)
log(0, "builtin (ctzl), ");
# else
log(0, "emulated, ");
# endif
log(0, "ffs32: ");
# if __has_builtin(__builtin_ffs)
log(0, "builtin, ");
# elif __has_builtin(__builtin_ctz)
log(0, "builtin (ctzl), ");
# else
log(0, "emulated, ");
# endif
log(0, "\n");
}

View File

@@ -1,145 +0,0 @@
/* debug.c - debug/log management
*
* Copyright (C) 2021-2023 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#ifndef DEBUG_DEBUG
#define DEBUG_DEBUG
#endif
#include "debug.h"
static long long timer_start; /* in nanosecond */
static int level = 0; /* output log when < level */
static int flush = false; /* force flush after logs */
static FILE *stream = NULL; /* stream to use */
/**
* debug_level_set() - set debug level.
* @_level: debug level (integer).
*/
void debug_level_set(int _level)
{
level = _level;
# ifdef DEBUG_DEBUG_C
log(0, "debug level set to %u\n", level);
# endif
}
/**
* debug_level_get() - get debug level.
* @return: current level debug (integer).
*/
int debug_level_get(void)
{
return level;
}
void debug_stream_set(FILE *_stream)
{
stream = _stream;
# ifdef DEBUG_DEBUG_C
log(0, "stream set to %d\n", stream? fileno(stream): -1);
# endif
}
void debug_flush_set(bool _flush)
{
flush = _flush;
# ifdef DEBUG_DEBUG_C
log(0, "debug flush %s.\n", flush? "set": "unset");
# endif
}
void debug_init(int _level, FILE *_stream, bool _flush)
{
struct timespec timer;
debug_stream_set(_stream);
debug_level_set(_level);
debug_flush_set(_flush);
if (!clock_gettime(CLOCK_MONOTONIC, &timer)) {
timer_start = timer.tv_sec * NANOSEC + timer.tv_nsec;
}
else {
timer_start = 0;
}
log(0, "timer started.\n");
}
long long debug_timer_elapsed(void)
{
struct timespec timer;
clock_gettime(CLOCK_MONOTONIC, &timer);
return (timer.tv_sec * NANOSEC + timer.tv_nsec) - timer_start;
}
/**
* debug() - log function
* @lev: log level
* @timestamp: boolean, print timestamp if true
* @indent: indent level (2 spaces each)
* @src: source file/func name (or NULL)
* @line: line number
*/
void debug(int lev, bool timestamp, int indent, const char *src,
int line, const char *fmt, ...)
{
if (!stream || lev > level)
return;
va_list ap;
if (indent)
fprintf(stream, "%*s", 2*(indent-1), "");
if (timestamp) {
long long diff = debug_timer_elapsed();
fprintf(stream, "%lld.%03lld ", diff/NANOSEC, (diff/1000000)%1000);
fprintf(stream, "%010lld ", diff);
}
if (src) {
if (line)
fprintf(stream, "[%s:%u] ", src, line);
else
fprintf(stream, "[%s] ", src);
}
va_start(ap, fmt);
vfprintf(stream, fmt, ap);
va_end(ap);
if (flush)
fflush(stream);
}
#ifdef BIN_debug
#include <unistd.h>
int main()
{
int foo=1;
debug_init(5);
log(0, "log0=%d\n", foo++);
log(1, "log1=%d\n", foo++);
log(2, "log2=%d\n", foo++);
log_i(2, "log_i 2=%d\n", foo++);
log_i(5, "log_i 5=%d\n", foo++);
log_i(6, "log_i 6=%d\n", foo++);
log_it(4, "log_it 4=%d\n", foo++);
log_f(1, "log_f 5=%d\n", foo++);
}
#endif

View File

@@ -1,29 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* inspired from kernel's <fs/namei.h>
*/
#include "hash.h"
/* Return the hash of a string of known length */
unsigned int hash_string(const void *salt, const char *name, unsigned int len)
{
unsigned long hash = init_name_hash(salt);
while (len--)
hash = partial_name_hash((unsigned char)*name++, hash);
return end_name_hash(hash);
}
/* Return the "hash_len" (hash and length) of a null-terminated string */
u64 hashlen_string(const void *salt, const char *name)
{
unsigned long hash = init_name_hash(salt);
unsigned long len = 0, c;
c = (unsigned char)*name;
while (c) {
len++;
hash = partial_name_hash(c, hash);
c = (unsigned char)name[len];
}
return hashlen_create(end_name_hash(hash), len);
}

View File

@@ -1,20 +0,0 @@
/* pjwhash.c - PJW hash function.
*
* Copyright (C) 2021-2022 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#define _pjw_inline extern
//#include "bits.h"
//extern unsigned int pjwhash (const void* key, uint length);
#include "pjwhash.h"
#include "pjwhash-inline.h"

View File

@@ -1,173 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* adapted from Linux kernel lib/plist.c
*
* Descending-priority-sorted double-linked list
*
* (C) 2002-2003 Intel Corp
* Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>.
*
* 2001-2005 (c) MontaVista Software, Inc.
* Daniel Walker <dwalker@mvista.com>
*
* (C) 2005 Thomas Gleixner <tglx@linutronix.de>
*
* Simplifications of the original code by
* Oleg Nesterov <oleg@tv-sign.ru>
*
* Based on simple lists (include/linux/list.h).
*
* This file contains the add / del functions which are considered to
* be too large to inline. See include/linux/plist.h for further
* information.
*/
#include "plist.h"
#include "bug.h"
#ifdef DEBUG_PLIST
static struct plist_head test_head;
static void plist_check_prev_next(struct list_head *t, struct list_head *p,
struct list_head *n)
{
WARN(n->prev != p || p->next != n,
"top: %p, n: %p, p: %p\n"
"prev: %p, n: %p, p: %p\n"
"next: %p, n: %p, p: %p\n",
t, t->next, t->prev,
p, p->next, p->prev,
n, n->next, n->prev);
}
static void plist_check_list(struct list_head *top)
{
struct list_head *prev = top, *next = top->next;
plist_check_prev_next(top, prev, next);
while (next != top) {
prev = next;
next = prev->next;
plist_check_prev_next(top, prev, next);
}
}
static void plist_check_head(struct plist_head *head)
{
if (!plist_head_empty(head))
plist_check_list(&plist_first(head)->prio_list);
plist_check_list(&head->node_list);
}
#else
# define plist_check_head(h) do { } while (0)
#endif
/**
* plist_add - add @node to @head
*
* @node: &struct plist_node pointer
* @head: &struct plist_head pointer
*/
void plist_add(struct plist_node *node, struct plist_head *head)
{
struct plist_node *first, *iter, *prev = NULL;
struct list_head *node_next = &head->node_list;
plist_check_head(head);
WARN_ON(!plist_node_empty(node));
WARN_ON(!list_empty(&node->prio_list));
if (plist_head_empty(head))
goto ins_node;
first = iter = plist_first(head);
do {
if (node->prio < iter->prio) {
node_next = &iter->node_list;
break;
}
prev = iter;
iter = list_entry(iter->prio_list.next,
struct plist_node, prio_list);
} while (iter != first);
if (!prev || prev->prio != node->prio)
list_add_tail(&node->prio_list, &iter->prio_list);
ins_node:
list_add_tail(&node->node_list, node_next);
plist_check_head(head);
}
/**
* plist_del - Remove a @node from plist.
*
* @node: &struct plist_node pointer - entry to be removed
* @head: &struct plist_head pointer - list head
*/
void plist_del(struct plist_node *node, struct plist_head *head)
{
plist_check_head(head);
if (!list_empty(&node->prio_list)) {
if (node->node_list.next != &head->node_list) {
struct plist_node *next;
next = list_entry(node->node_list.next,
struct plist_node, node_list);
/* add the next plist_node into prio_list */
if (list_empty(&next->prio_list))
list_add(&next->prio_list, &node->prio_list);
}
list_del_init(&node->prio_list);
}
list_del_init(&node->node_list);
plist_check_head(head);
}
/**
* plist_requeue - Requeue @node at end of same-prio entries.
*
* This is essentially an optimized plist_del() followed by
* plist_add(). It moves an entry already in the plist to
* after any other same-priority entries.
*
* @node: &struct plist_node pointer - entry to be moved
* @head: &struct plist_head pointer - list head
*/
void plist_requeue(struct plist_node *node, struct plist_head *head)
{
struct plist_node *iter;
struct list_head *node_next = &head->node_list;
plist_check_head(head);
BUG_ON(plist_head_empty(head));
BUG_ON(plist_node_empty(node));
if (node == plist_last(head))
return;
iter = plist_next(node);
if (node->prio != iter->prio)
return;
plist_del(node, head);
plist_for_each_continue(iter, head) {
if (node->prio != iter->prio) {
node_next = &iter->node_list;
break;
}
}
list_add_tail(&node->node_list, node_next);
plist_check_head(head);
}

View File

@@ -1,219 +0,0 @@
/* pool.c - A simple pool manager.
*
* Copyright (C) 2021-2022 Bruno Raoult ("br")
* Licensed under the GNU General Public License v3.0 or later.
* Some rights reserved. See COPYING.
*
* You should have received a copy of the GNU General Public License along with this
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
*
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
*
*/
#include <stddef.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "list.h"
#include "pool.h"
#include "debug.h"
#include "bits.h"
void pool_stats(pool_t *pool)
{
if (pool) {
block_t *block;
log_f(1, "[%s] pool [%p]: blocks:%u avail:%u alloc:%u grow:%u eltsize:%zu\n",
pool->name, (void *)pool, pool->nblocks, pool->available,
pool->allocated, pool->growsize, pool->eltsize);
log(5, "\tblocks: ");
list_for_each_entry(block, &pool->list_blocks, list_blocks) {
log(5, "%p ", block);
}
log(5, "\n");
}
}
pool_t *pool_create(const char *name, u32 growsize, size_t eltsize)
{
pool_t *pool;
# ifdef DEBUG_POOL
log_f(1, "name=[%s] growsize=%u eltsize=%zu\n", name, growsize, eltsize);
# endif
/* we need at least sizeof(struct list_head) space in pool elements
*/
if (eltsize < sizeof (struct list_head)) {
# ifdef DEBUG_POOL
log_f(1, "[%s]: structure size too small (%zu < %zu), adjusting to %zu.\n",
name, eltsize, sizeof(struct list_head), sizeof(struct list_head));
# endif
eltsize = sizeof(struct list_head);
}
if ((pool = malloc(sizeof (*pool)))) {
strncpy(pool->name, name, POOL_NAME_LENGTH - 1);
pool->name[POOL_NAME_LENGTH - 1] = 0;
pool->growsize = growsize;
pool->eltsize = eltsize;
pool->available = 0;
pool->allocated = 0;
pool->nblocks = 0;
INIT_LIST_HEAD(&pool->list_available);
INIT_LIST_HEAD(&pool->list_blocks);
} else {
errno = ENOMEM;
}
return pool;
}
static u32 _pool_add(pool_t *pool, struct list_head *elt)
{
# ifdef DEBUG_POOL
log_f(6, "pool=%p &head=%p elt=%p off1=%zu off2=%zu\n",
(void *)pool, (void *)&pool->list_available, (void *)elt,
(void *)&pool->list_available - (void *)pool,
offsetof(pool_t, list_available));
# endif
list_add(elt, &pool->list_available);
return ++pool->available;
}
u32 pool_add(pool_t *pool, void *elt)
{
return _pool_add(pool, elt);
}
static struct list_head *_pool_get(pool_t *pool)
{
struct list_head *res = pool->list_available.next;
pool->available--;
list_del(res);
return res;
}
void *pool_get(pool_t *pool)
{
if (!pool)
return NULL;
if (!pool->available) {
block_t *block = malloc(sizeof(block_t) + pool->eltsize * pool->growsize);
if (!block) {
# ifdef DEBUG_POOL
log_f(1, "[%s]: failed block allocation\n", pool->name);
# endif
errno = ENOMEM;
return NULL;
}
/* maintain list of allocated blocks
*/
list_add(&block->list_blocks, &pool->list_blocks);
pool->nblocks++;
# ifdef DEBUG_POOL
log_f(1, "[%s]: growing pool from %u to %u elements. block=%p nblocks=%u\n",
pool->name,
pool->allocated,
pool->allocated + pool->growsize,
block,
pool->nblocks);
# endif
pool->allocated += pool->growsize;
for (u32 i = 0; i < pool->growsize; ++i) {
void *cur = block->data + i * pool->eltsize;
# ifdef DEBUG_POOL
log_f(7, "alloc=%p cur=%p\n", block, cur);
# endif
_pool_add(pool, (struct list_head *)cur);
}
}
/* this is the effective address of the object (and also the
* pool list_head address)
*/
return _pool_get(pool);
}
void pool_destroy(pool_t *pool)
{
block_t *block, *tmp;
if (!pool)
return;
/* release memory blocks */
# ifdef DEBUG_POOL
log_f(1, "[%s]: releasing %d blocks and main structure\n", pool->name, pool->nblocks);
log(5, "blocks:");
# endif
list_for_each_entry_safe(block, tmp, &pool->list_blocks, list_blocks) {
# ifdef DEBUG_POOL
log(5, " %p", block);
# endif
list_del(&block->list_blocks);
free(block);
}
# ifdef DEBUG_POOL
log(5, "\n");
# endif
free(pool);
}
#ifdef BIN_pool
struct d {
u16 data1;
char c;
struct list_head list;
};
static LIST_HEAD (head);
int main(int ac, char**av)
{
pool_t *pool;
int total;
int action=0;
u16 icur=0;
char ccur='z';
struct d *elt;
debug_init(3);
log_f(1, "%s: sizeof(d)=%lu sizeof(*d)=%lu off=%lu\n", *av, sizeof(elt),
sizeof(*elt), offsetof(struct d, list));
if ((pool = pool_create("dummy", 3, sizeof(*elt)))) {
pool_stats(pool);
for (int cur=1; cur<ac; ++cur) {
total = atoi(av[cur]);
if (action == 0) { /* add elt to list */
log_f(2, "adding %d elements\n", total);
for (int i = 0; i < total; ++i) {
elt = pool_get(pool);
elt->data1 = icur++;
elt->c = ccur--;
list_add(&elt->list, &head);
}
pool_stats(pool);
action = 1;
} else { /* remove one elt from list */
log_f(2, "deleting %d elements\n", total);
for (int i = 0; i < total; ++i) {
if (!list_empty(&head)) {
elt = list_last_entry(&head, struct d, list);
printf("elt=[%d, %c]\n", elt->data1, elt->c);
list_del(&elt->list);
pool_add(pool, elt);
}
}
pool_stats(pool);
action = 0;
}
}
}
pool_stats(pool);
pool_destroy(pool);
}
#endif

View File

@@ -1,155 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_GENERIC_UNALIGNED_H
#define __ASM_GENERIC_UNALIGNED_H
/*
* This is the most generic implementation of unaligned accesses
* and should work almost anywhere.
*/
#include <linux/unaligned/packed_struct.h>
#include <asm/byteorder.h>
#define __get_unaligned_t(type, ptr) ({ \
const struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \
__pptr->x; \
})
#define __put_unaligned_t(type, val, ptr) do { \
struct { type x; } __packed *__pptr = (typeof(__pptr))(ptr); \
__pptr->x = (val); \
} while (0)
#define get_unaligned(ptr) __get_unaligned_t(typeof(*(ptr)), (ptr))
#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
static inline u16 get_unaligned_le16(const void *p)
{
return le16_to_cpu(__get_unaligned_t(__le16, p));
}
static inline u32 get_unaligned_le32(const void *p)
{
return le32_to_cpu(__get_unaligned_t(__le32, p));
}
static inline u64 get_unaligned_le64(const void *p)
{
return le64_to_cpu(__get_unaligned_t(__le64, p));
}
static inline void put_unaligned_le16(u16 val, void *p)
{
__put_unaligned_t(__le16, cpu_to_le16(val), p);
}
static inline void put_unaligned_le32(u32 val, void *p)
{
__put_unaligned_t(__le32, cpu_to_le32(val), p);
}
static inline void put_unaligned_le64(u64 val, void *p)
{
__put_unaligned_t(__le64, cpu_to_le64(val), p);
}
static inline u16 get_unaligned_be16(const void *p)
{
return be16_to_cpu(__get_unaligned_t(__be16, p));
}
static inline u32 get_unaligned_be32(const void *p)
{
return be32_to_cpu(__get_unaligned_t(__be32, p));
}
static inline u64 get_unaligned_be64(const void *p)
{
return be64_to_cpu(__get_unaligned_t(__be64, p));
}
static inline void put_unaligned_be16(u16 val, void *p)
{
__put_unaligned_t(__be16, cpu_to_be16(val), p);
}
static inline void put_unaligned_be32(u32 val, void *p)
{
__put_unaligned_t(__be32, cpu_to_be32(val), p);
}
static inline void put_unaligned_be64(u64 val, void *p)
{
__put_unaligned_t(__be64, cpu_to_be64(val), p);
}
static inline u32 __get_unaligned_be24(const u8 *p)
{
return p[0] << 16 | p[1] << 8 | p[2];
}
static inline u32 get_unaligned_be24(const void *p)
{
return __get_unaligned_be24(p);
}
static inline u32 __get_unaligned_le24(const u8 *p)
{
return p[0] | p[1] << 8 | p[2] << 16;
}
static inline u32 get_unaligned_le24(const void *p)
{
return __get_unaligned_le24(p);
}
static inline void __put_unaligned_be24(const u32 val, u8 *p)
{
*p++ = val >> 16;
*p++ = val >> 8;
*p++ = val;
}
static inline void put_unaligned_be24(const u32 val, void *p)
{
__put_unaligned_be24(val, p);
}
static inline void __put_unaligned_le24(const u32 val, u8 *p)
{
*p++ = val;
*p++ = val >> 8;
*p++ = val >> 16;
}
static inline void put_unaligned_le24(const u32 val, void *p)
{
__put_unaligned_le24(val, p);
}
static inline void __put_unaligned_be48(const u64 val, u8 *p)
{
*p++ = val >> 40;
*p++ = val >> 32;
*p++ = val >> 24;
*p++ = val >> 16;
*p++ = val >> 8;
*p++ = val;
}
static inline void put_unaligned_be48(const u64 val, void *p)
{
__put_unaligned_be48(val, p);
}
static inline u64 __get_unaligned_be48(const u8 *p)
{
return (u64)p[0] << 40 | (u64)p[1] << 32 | (u64)p[2] << 24 |
p[3] << 16 | p[4] << 8 | p[5];
}
static inline u64 get_unaligned_be48(const void *p)
{
return __get_unaligned_be48(p);
}
#endif /* __ASM_GENERIC_UNALIGNED_H */

View File

@@ -1,61 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* See Documentation/core-api/circular-buffers.rst for more information.
*/
#include <stdlib.h>
#include <stdio.h>
#define CIRC_BUF(name, type, bits) \
struct s##name { \
type buf[1 << (bits)]; \
int head; \
int tail; \
} name = { \
{ 0 }, \
0, \
0 };
struct circ_buf {
char *buf;
int head;
int tail;
};
/* Return count in buffer. */
#define CIRC_CNT(head,tail,size) (((head) - (tail)) & ((size)-1))
/* Return space available, 0..size-1. We always leave one free char
as a completely full buffer has head == tail, which is the same as
empty. */
#define CIRC_SPACE(head,tail,size) CIRC_CNT((tail),((head)+1),(size))
/* Return count up to the end of the buffer. Carefully avoid
accessing head and tail more than once, so they can change
underneath us without returning inconsistent results. */
#define CIRC_CNT_TO_END(head,tail,size) \
({int end = (size) - (tail); \
int n = ((head) + end) & ((size)-1); \
n < end ? n : end;})
/* Return space available up to the end of the buffer. */
#define CIRC_SPACE_TO_END(head,tail,size) \
({int end = (size) - 1 - (head); \
int n = (end + (tail)) & ((size)-1); \
n <= end ? n : end+1;})
int main(int ac, char **av)
{
int size = 5;
if (ac > 8) {
size = atoi(*(av + 1));
}
printf("size-%d\n", size);
CIRC_BUF(foo, int, 5);
printf("sizeof(elt)=%lu\n", sizeof(foo.buf[0]));
printf("sizeof(buf)=%lu\n", sizeof(foo.buf));
}

View File

@@ -1,44 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* See Documentation/core-api/circular-buffers.rst for more information.
*/
#ifndef _LINUX_CIRC_BUF_H
#define _LINUX_CIRC_BUF_H 1
#define CIRC_BUF(name, type, bits) \
struct s##name { \
type buf[1 << (bits)]; \
int head; \
int tail; \
};
struct circ_buf {
char *buf;
int head;
int tail;
};
/* Return count in buffer. */
#define CIRC_CNT(head,tail,size) (((head) - (tail)) & ((size)-1))
/* Return space available, 0..size-1. We always leave one free char
as a completely full buffer has head == tail, which is the same as
empty. */
#define CIRC_SPACE(head,tail,size) CIRC_CNT((tail),((head)+1),(size))
/* Return count up to the end of the buffer. Carefully avoid
accessing head and tail more than once, so they can change
underneath us without returning inconsistent results. */
#define CIRC_CNT_TO_END(head,tail,size) \
({int end = (size) - (tail); \
int n = ((head) + end) & ((size)-1); \
n < end ? n : end;})
/* Return space available up to the end of the buffer. */
#define CIRC_SPACE_TO_END(head,tail,size) \
({int end = (size) - 1 - (head); \
int n = (end + (tail)) & ((size)-1); \
n <= end ? n : end+1;})
#endif /* _LINUX_CIRC_BUF_H */

View File

@@ -1,8 +0,0 @@
#include <stdio.h>
#include "hash.h"
int main()
{
printf("foo\n");
return 1;
}

View File

@@ -1,253 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Taken from linux kernel: lib/list_sort.c
*/
#include "list_sort.h"
#include "list.h"
#include "bits.h"
#include "likely.h"
/*
* Returns a list organized in an intermediate format suited
* to chaining of merge() calls: null-terminated, no reserved or
* sentinel head node, "prev" links not maintained.
*/
__attribute__((nonnull(2,3,4)))
static struct list_head *merge(void *priv, list_cmp_func_t cmp,
struct list_head *a, struct list_head *b)
{
struct list_head *head, **tail = &head;
for (;;) {
/* if equal, take 'a' -- important for sort stability */
if (cmp(priv, a, b) <= 0) {
*tail = a;
tail = &a->next;
a = a->next;
if (!a) {
*tail = b;
break;
}
} else {
*tail = b;
tail = &b->next;
b = b->next;
if (!b) {
*tail = a;
break;
}
}
}
return head;
}
/*
* Combine final list merge with restoration of standard doubly-linked
* list structure. This approach duplicates code from merge(), but
* runs faster than the tidier alternatives of either a separate final
* prev-link restoration pass, or maintaining the prev links
* throughout.
*/
__attribute__((nonnull(2,3,4,5)))
static void merge_final(void *priv, list_cmp_func_t cmp, struct list_head *head,
struct list_head *a, struct list_head *b)
{
struct list_head *tail = head;
u8 count = 0;
for (;;) {
/* if equal, take 'a' -- important for sort stability */
if (cmp(priv, a, b) <= 0) {
tail->next = a;
a->prev = tail;
tail = a;
a = a->next;
if (!a)
break;
} else {
tail->next = b;
b->prev = tail;
tail = b;
b = b->next;
if (!b) {
b = a;
break;
}
}
}
/* Finish linking remainder of list b on to tail */
tail->next = b;
do {
/*
* If the merge is highly unbalanced (e.g. the input is
* already sorted), this loop may run many iterations.
* Continue callbacks to the client even though no
* element comparison is needed, so the client's cmp()
* routine can invoke cond_resched() periodically.
*/
if (unlikely(!++count))
cmp(priv, b, b);
b->prev = tail;
tail = b;
b = b->next;
} while (b);
/* And the final links to make a circular doubly-linked list */
tail->next = head;
head->prev = tail;
}
/**
* list_sort - sort a list
* @priv: private data, opaque to list_sort(), passed to @cmp
* @head: the list to sort
* @cmp: the elements comparison function
*
* The comparison function @cmp must return > 0 if @a should sort after
* @b ("@a > @b" if you want an ascending sort), and <= 0 if @a should
* sort before @b *or* their original order should be preserved. It is
* always called with the element that came first in the input in @a,
* and list_sort is a stable sort, so it is not necessary to distinguish
* the @a < @b and @a == @b cases.
*
* This is compatible with two styles of @cmp function:
* - The traditional style which returns <0 / =0 / >0, or
* - Returning a boolean 0/1.
* The latter offers a chance to save a few cycles in the comparison
* (which is used by e.g. plug_ctx_cmp() in block/blk-mq.c).
*
* A good way to write a multi-word comparison is::
*
* if (a->high != b->high)
* return a->high > b->high;
* if (a->middle != b->middle)
* return a->middle > b->middle;
* return a->low > b->low;
*
*
* This mergesort is as eager as possible while always performing at least
* 2:1 balanced merges. Given two pending sublists of size 2^k, they are
* merged to a size-2^(k+1) list as soon as we have 2^k following elements.
*
* Thus, it will avoid cache thrashing as long as 3*2^k elements can
* fit into the cache. Not quite as good as a fully-eager bottom-up
* mergesort, but it does use 0.2*n fewer comparisons, so is faster in
* the common case that everything fits into L1.
*
*
* The merging is controlled by "count", the number of elements in the
* pending lists. This is beautifully simple code, but rather subtle.
*
* Each time we increment "count", we set one bit (bit k) and clear
* bits k-1 .. 0. Each time this happens (except the very first time
* for each bit, when count increments to 2^k), we merge two lists of
* size 2^k into one list of size 2^(k+1).
*
* This merge happens exactly when the count reaches an odd multiple of
* 2^k, which is when we have 2^k elements pending in smaller lists,
* so it's safe to merge away two lists of size 2^k.
*
* After this happens twice, we have created two lists of size 2^(k+1),
* which will be merged into a list of size 2^(k+2) before we create
* a third list of size 2^(k+1), so there are never more than two pending.
*
* The number of pending lists of size 2^k is determined by the
* state of bit k of "count" plus two extra pieces of information:
*
* - The state of bit k-1 (when k == 0, consider bit -1 always set), and
* - Whether the higher-order bits are zero or non-zero (i.e.
* is count >= 2^(k+1)).
*
* There are six states we distinguish. "x" represents some arbitrary
* bits, and "y" represents some arbitrary non-zero bits:
* 0: 00x: 0 pending of size 2^k; x pending of sizes < 2^k
* 1: 01x: 0 pending of size 2^k; 2^(k-1) + x pending of sizes < 2^k
* 2: x10x: 0 pending of size 2^k; 2^k + x pending of sizes < 2^k
* 3: x11x: 1 pending of size 2^k; 2^(k-1) + x pending of sizes < 2^k
* 4: y00x: 1 pending of size 2^k; 2^k + x pending of sizes < 2^k
* 5: y01x: 2 pending of size 2^k; 2^(k-1) + x pending of sizes < 2^k
* (merge and loop back to state 2)
*
* We gain lists of size 2^k in the 2->3 and 4->5 transitions (because
* bit k-1 is set while the more significant bits are non-zero) and
* merge them away in the 5->2 transition. Note in particular that just
* before the 5->2 transition, all lower-order bits are 11 (state 3),
* so there is one list of each smaller size.
*
* When we reach the end of the input, we merge all the pending
* lists, from smallest to largest. If you work through cases 2 to
* 5 above, you can see that the number of elements we merge with a list
* of size 2^k varies from 2^(k-1) (cases 3 and 5 when x == 0) to
* 2^(k+1) - 1 (second merge of case 5 when x == 2^(k-1) - 1).
*/
__attribute__((nonnull(2,3)))
void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp)
{
struct list_head *list = head->next, *pending = NULL;
size_t count = 0; /* Count of pending */
if (list == head->prev) /* Zero or one elements */
return;
/* Convert to a null-terminated singly-linked list. */
head->prev->next = NULL;
/*
* Data structure invariants:
* - All lists are singly linked and null-terminated; prev
* pointers are not maintained.
* - pending is a prev-linked "list of lists" of sorted
* sublists awaiting further merging.
* - Each of the sorted sublists is power-of-two in size.
* - Sublists are sorted by size and age, smallest & newest at front.
* - There are zero to two sublists of each size.
* - A pair of pending sublists are merged as soon as the number
* of following pending elements equals their size (i.e.
* each time count reaches an odd multiple of that size).
* That ensures each later final merge will be at worst 2:1.
* - Each round consists of:
* - Merging the two sublists selected by the highest bit
* which flips when count is incremented, and
* - Adding an element from the input as a size-1 sublist.
*/
do {
size_t bits;
struct list_head **tail = &pending;
/* Find the least-significant clear bit in count */
for (bits = count; bits & 1; bits >>= 1)
tail = &(*tail)->prev;
/* Do the indicated merge */
if (likely(bits)) {
struct list_head *a = *tail, *b = a->prev;
a = merge(priv, cmp, b, a);
/* Install the merged result in place of the inputs */
a->prev = b->prev;
*tail = a;
}
/* Move one element from input list to pending */
list->prev = pending;
pending = list;
list = list->next;
pending->next = NULL;
count++;
} while (list);
/* End of input; merge together all the pending lists. */
list = pending;
pending = pending->prev;
for (;;) {
struct list_head *next = pending->prev;
if (!next)
break;
list = merge(priv, cmp, pending, list);
pending = next;
}
/* The final merge, rebuilding prev links */
merge_final(priv, cmp, head, pending, list);
}

View File

@@ -1,20 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Taken from linux kernel: lib/list_sort.c
*/
#ifndef _BR_LIST_SORT_H
#define _BR_LIST_SORT_H
//#include <linux/types.h>
struct list_head;
typedef int __attribute__((nonnull(2,3))) (*list_cmp_func_t)(void *,
const struct list_head *, const struct list_head *);
__attribute__((nonnull(2,3)))
void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp);
#endif /* _BR_LIST_SORT */

View File

@@ -1,46 +0,0 @@
#ifndef _LINUX_UNALIGNED_PACKED_STRUCT_H
#define _LINUX_UNALIGNED_PACKED_STRUCT_H
#include <linux/types.h>
struct __una_u16 { u16 x; } __packed;
struct __una_u32 { u32 x; } __packed;
struct __una_u64 { u64 x; } __packed;
static inline u16 __get_unaligned_cpu16(const void *p)
{
const struct __una_u16 *ptr = (const struct __una_u16 *)p;
return ptr->x;
}
static inline u32 __get_unaligned_cpu32(const void *p)
{
const struct __una_u32 *ptr = (const struct __una_u32 *)p;
return ptr->x;
}
static inline u64 __get_unaligned_cpu64(const void *p)
{
const struct __una_u64 *ptr = (const struct __una_u64 *)p;
return ptr->x;
}
static inline void __put_unaligned_cpu16(u16 val, void *p)
{
struct __una_u16 *ptr = (struct __una_u16 *)p;
ptr->x = val;
}
static inline void __put_unaligned_cpu32(u32 val, void *p)
{
struct __una_u32 *ptr = (struct __una_u32 *)p;
ptr->x = val;
}
static inline void __put_unaligned_cpu64(u64 val, void *p)
{
struct __una_u64 *ptr = (struct __una_u64 *)p;
ptr->x = val;
}
#endif /* _LINUX_UNALIGNED_PACKED_STRUCT_H */

View File

@@ -1,489 +0,0 @@
/*
* xxHash - Extremely Fast Hash algorithm
* Copyright (C) 2012-2016, Yann Collet.
*
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation. This program is dual-licensed; you may select
* either version 2 of the GNU General Public License ("GPL") or BSD license
* ("BSD").
*
* You can contact the author at:
* - xxHash homepage: https://cyan4973.github.io/xxHash/
* - xxHash source repository: https://github.com/Cyan4973/xxHash
*/
#include <errno.h>
#include <string.h>
#include <asm/byteorder.h>
//#include <linux/compiler.h>
// #include <linux/kernel.h>
#include "xxhash.h"
#include "bits.h"
#include "asm/unaligned.h"
/*-*************************************
* Macros
**************************************/
#define xxh_rotl32(x, r) ((x << r) | (x >> (32 - r)))
#define xxh_rotl64(x, r) ((x << r) | (x >> (64 - r)))
#ifdef __LITTLE_ENDIAN
# define XXH_CPU_LITTLE_ENDIAN 1
#else
# define XXH_CPU_LITTLE_ENDIAN 0
#endif
/*-*************************************
* Constants
**************************************/
static const uint32_t PRIME32_1 = 2654435761U;
static const uint32_t PRIME32_2 = 2246822519U;
static const uint32_t PRIME32_3 = 3266489917U;
static const uint32_t PRIME32_4 = 668265263U;
static const uint32_t PRIME32_5 = 374761393U;
static const uint64_t PRIME64_1 = 11400714785074694791ULL;
static const uint64_t PRIME64_2 = 14029467366897019727ULL;
static const uint64_t PRIME64_3 = 1609587929392839161ULL;
static const uint64_t PRIME64_4 = 9650029242287828579ULL;
static const uint64_t PRIME64_5 = 2870177450012600261ULL;
/*-**************************
* Utils
***************************/
void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src)
{
memcpy(dst, src, sizeof(*dst));
}
void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src)
{
memcpy(dst, src, sizeof(*dst));
}
/*-***************************
* Simple Hash Functions
****************************/
static uint32_t xxh32_round(uint32_t seed, const uint32_t input)
{
seed += input * PRIME32_2;
seed = xxh_rotl32(seed, 13);
seed *= PRIME32_1;
return seed;
}
uint32_t xxh32(const void *input, const size_t len, const uint32_t seed)
{
const uint8_t *p = (const uint8_t *)input;
const uint8_t *b_end = p + len;
uint32_t h32;
if (len >= 16) {
const uint8_t *const limit = b_end - 16;
uint32_t v1 = seed + PRIME32_1 + PRIME32_2;
uint32_t v2 = seed + PRIME32_2;
uint32_t v3 = seed + 0;
uint32_t v4 = seed - PRIME32_1;
do {
v1 = xxh32_round(v1, get_unaligned_le32(p));
p += 4;
v2 = xxh32_round(v2, get_unaligned_le32(p));
p += 4;
v3 = xxh32_round(v3, get_unaligned_le32(p));
p += 4;
v4 = xxh32_round(v4, get_unaligned_le32(p));
p += 4;
} while (p <= limit);
h32 = xxh_rotl32(v1, 1) + xxh_rotl32(v2, 7) +
xxh_rotl32(v3, 12) + xxh_rotl32(v4, 18);
} else {
h32 = seed + PRIME32_5;
}
h32 += (uint32_t)len;
while (p + 4 <= b_end) {
h32 += get_unaligned_le32(p) * PRIME32_3;
h32 = xxh_rotl32(h32, 17) * PRIME32_4;
p += 4;
}
while (p < b_end) {
h32 += (*p) * PRIME32_5;
h32 = xxh_rotl32(h32, 11) * PRIME32_1;
p++;
}
h32 ^= h32 >> 15;
h32 *= PRIME32_2;
h32 ^= h32 >> 13;
h32 *= PRIME32_3;
h32 ^= h32 >> 16;
return h32;
}
static uint64_t xxh64_round(uint64_t acc, const uint64_t input)
{
acc += input * PRIME64_2;
acc = xxh_rotl64(acc, 31);
acc *= PRIME64_1;
return acc;
}
static uint64_t xxh64_merge_round(uint64_t acc, uint64_t val)
{
val = xxh64_round(0, val);
acc ^= val;
acc = acc * PRIME64_1 + PRIME64_4;
return acc;
}
uint64_t xxh64(const void *input, const size_t len, const uint64_t seed)
{
const uint8_t *p = (const uint8_t *)input;
const uint8_t *const b_end = p + len;
uint64_t h64;
if (len >= 32) {
const uint8_t *const limit = b_end - 32;
uint64_t v1 = seed + PRIME64_1 + PRIME64_2;
uint64_t v2 = seed + PRIME64_2;
uint64_t v3 = seed + 0;
uint64_t v4 = seed - PRIME64_1;
do {
v1 = xxh64_round(v1, get_unaligned_le64(p));
p += 8;
v2 = xxh64_round(v2, get_unaligned_le64(p));
p += 8;
v3 = xxh64_round(v3, get_unaligned_le64(p));
p += 8;
v4 = xxh64_round(v4, get_unaligned_le64(p));
p += 8;
} while (p <= limit);
h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) +
xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18);
h64 = xxh64_merge_round(h64, v1);
h64 = xxh64_merge_round(h64, v2);
h64 = xxh64_merge_round(h64, v3);
h64 = xxh64_merge_round(h64, v4);
} else {
h64 = seed + PRIME64_5;
}
h64 += (uint64_t)len;
while (p + 8 <= b_end) {
const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p));
h64 ^= k1;
h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;
p += 8;
}
if (p + 4 <= b_end) {
h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1;
h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
p += 4;
}
while (p < b_end) {
h64 ^= (*p) * PRIME64_5;
h64 = xxh_rotl64(h64, 11) * PRIME64_1;
p++;
}
h64 ^= h64 >> 33;
h64 *= PRIME64_2;
h64 ^= h64 >> 29;
h64 *= PRIME64_3;
h64 ^= h64 >> 32;
return h64;
}
/*-**************************************************
* Advanced Hash Functions
***************************************************/
void xxh32_reset(struct xxh32_state *statePtr, const uint32_t seed)
{
/* use a local state for memcpy() to avoid strict-aliasing warnings */
struct xxh32_state state;
memset(&state, 0, sizeof(state));
state.v1 = seed + PRIME32_1 + PRIME32_2;
state.v2 = seed + PRIME32_2;
state.v3 = seed + 0;
state.v4 = seed - PRIME32_1;
memcpy(statePtr, &state, sizeof(state));
}
void xxh64_reset(struct xxh64_state *statePtr, const uint64_t seed)
{
/* use a local state for memcpy() to avoid strict-aliasing warnings */
struct xxh64_state state;
memset(&state, 0, sizeof(state));
state.v1 = seed + PRIME64_1 + PRIME64_2;
state.v2 = seed + PRIME64_2;
state.v3 = seed + 0;
state.v4 = seed - PRIME64_1;
memcpy(statePtr, &state, sizeof(state));
}
int xxh32_update(struct xxh32_state *state, const void *input, const size_t len)
{
const uint8_t *p = (const uint8_t *)input;
const uint8_t *const b_end = p + len;
if (input == NULL)
return -EINVAL;
state->total_len_32 += (uint32_t)len;
state->large_len |= (len >= 16) | (state->total_len_32 >= 16);
if (state->memsize + len < 16) { /* fill in tmp buffer */
memcpy((uint8_t *)(state->mem32) + state->memsize, input, len);
state->memsize += (uint32_t)len;
return 0;
}
if (state->memsize) { /* some data left from previous update */
const uint32_t *p32 = state->mem32;
memcpy((uint8_t *)(state->mem32) + state->memsize, input,
16 - state->memsize);
state->v1 = xxh32_round(state->v1, get_unaligned_le32(p32));
p32++;
state->v2 = xxh32_round(state->v2, get_unaligned_le32(p32));
p32++;
state->v3 = xxh32_round(state->v3, get_unaligned_le32(p32));
p32++;
state->v4 = xxh32_round(state->v4, get_unaligned_le32(p32));
p32++;
p += 16-state->memsize;
state->memsize = 0;
}
if (p <= b_end - 16) {
const uint8_t *const limit = b_end - 16;
uint32_t v1 = state->v1;
uint32_t v2 = state->v2;
uint32_t v3 = state->v3;
uint32_t v4 = state->v4;
do {
v1 = xxh32_round(v1, get_unaligned_le32(p));
p += 4;
v2 = xxh32_round(v2, get_unaligned_le32(p));
p += 4;
v3 = xxh32_round(v3, get_unaligned_le32(p));
p += 4;
v4 = xxh32_round(v4, get_unaligned_le32(p));
p += 4;
} while (p <= limit);
state->v1 = v1;
state->v2 = v2;
state->v3 = v3;
state->v4 = v4;
}
if (p < b_end) {
memcpy(state->mem32, p, (size_t)(b_end-p));
state->memsize = (uint32_t)(b_end-p);
}
return 0;
}
uint32_t xxh32_digest(const struct xxh32_state *state)
{
const uint8_t *p = (const uint8_t *)state->mem32;
const uint8_t *const b_end = (const uint8_t *)(state->mem32) +
state->memsize;
uint32_t h32;
if (state->large_len) {
h32 = xxh_rotl32(state->v1, 1) + xxh_rotl32(state->v2, 7) +
xxh_rotl32(state->v3, 12) + xxh_rotl32(state->v4, 18);
} else {
h32 = state->v3 /* == seed */ + PRIME32_5;
}
h32 += state->total_len_32;
while (p + 4 <= b_end) {
h32 += get_unaligned_le32(p) * PRIME32_3;
h32 = xxh_rotl32(h32, 17) * PRIME32_4;
p += 4;
}
while (p < b_end) {
h32 += (*p) * PRIME32_5;
h32 = xxh_rotl32(h32, 11) * PRIME32_1;
p++;
}
h32 ^= h32 >> 15;
h32 *= PRIME32_2;
h32 ^= h32 >> 13;
h32 *= PRIME32_3;
h32 ^= h32 >> 16;
return h32;
}
int xxh64_update(struct xxh64_state *state, const void *input, const size_t len)
{
const uint8_t *p = (const uint8_t *)input;
const uint8_t *const b_end = p + len;
if (input == NULL)
return -EINVAL;
state->total_len += len;
if (state->memsize + len < 32) { /* fill in tmp buffer */
memcpy(((uint8_t *)state->mem64) + state->memsize, input, len);
state->memsize += (uint32_t)len;
return 0;
}
if (state->memsize) { /* tmp buffer is full */
uint64_t *p64 = state->mem64;
memcpy(((uint8_t *)p64) + state->memsize, input,
32 - state->memsize);
state->v1 = xxh64_round(state->v1, get_unaligned_le64(p64));
p64++;
state->v2 = xxh64_round(state->v2, get_unaligned_le64(p64));
p64++;
state->v3 = xxh64_round(state->v3, get_unaligned_le64(p64));
p64++;
state->v4 = xxh64_round(state->v4, get_unaligned_le64(p64));
p += 32 - state->memsize;
state->memsize = 0;
}
if (p + 32 <= b_end) {
const uint8_t *const limit = b_end - 32;
uint64_t v1 = state->v1;
uint64_t v2 = state->v2;
uint64_t v3 = state->v3;
uint64_t v4 = state->v4;
do {
v1 = xxh64_round(v1, get_unaligned_le64(p));
p += 8;
v2 = xxh64_round(v2, get_unaligned_le64(p));
p += 8;
v3 = xxh64_round(v3, get_unaligned_le64(p));
p += 8;
v4 = xxh64_round(v4, get_unaligned_le64(p));
p += 8;
} while (p <= limit);
state->v1 = v1;
state->v2 = v2;
state->v3 = v3;
state->v4 = v4;
}
if (p < b_end) {
memcpy(state->mem64, p, (size_t)(b_end-p));
state->memsize = (uint32_t)(b_end - p);
}
return 0;
}
uint64_t xxh64_digest(const struct xxh64_state *state)
{
const uint8_t *p = (const uint8_t *)state->mem64;
const uint8_t *const b_end = (const uint8_t *)state->mem64 +
state->memsize;
uint64_t h64;
if (state->total_len >= 32) {
const uint64_t v1 = state->v1;
const uint64_t v2 = state->v2;
const uint64_t v3 = state->v3;
const uint64_t v4 = state->v4;
h64 = xxh_rotl64(v1, 1) + xxh_rotl64(v2, 7) +
xxh_rotl64(v3, 12) + xxh_rotl64(v4, 18);
h64 = xxh64_merge_round(h64, v1);
h64 = xxh64_merge_round(h64, v2);
h64 = xxh64_merge_round(h64, v3);
h64 = xxh64_merge_round(h64, v4);
} else {
h64 = state->v3 + PRIME64_5;
}
h64 += (uint64_t)state->total_len;
while (p + 8 <= b_end) {
const uint64_t k1 = xxh64_round(0, get_unaligned_le64(p));
h64 ^= k1;
h64 = xxh_rotl64(h64, 27) * PRIME64_1 + PRIME64_4;
p += 8;
}
if (p + 4 <= b_end) {
h64 ^= (uint64_t)(get_unaligned_le32(p)) * PRIME64_1;
h64 = xxh_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
p += 4;
}
while (p < b_end) {
h64 ^= (*p) * PRIME64_5;
h64 = xxh_rotl64(h64, 11) * PRIME64_1;
p++;
}
h64 ^= h64 >> 33;
h64 *= PRIME64_2;
h64 ^= h64 >> 29;
h64 *= PRIME64_3;
h64 ^= h64 >> 32;
return h64;
}

View File

@@ -1,259 +0,0 @@
/*
* xxHash - Extremely Fast Hash algorithm
* Copyright (C) 2012-2016, Yann Collet.
*
* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License version 2 as published by the
* Free Software Foundation. This program is dual-licensed; you may select
* either version 2 of the GNU General Public License ("GPL") or BSD license
* ("BSD").
*
* You can contact the author at:
* - xxHash homepage: https://cyan4973.github.io/xxHash/
* - xxHash source repository: https://github.com/Cyan4973/xxHash
*/
/*
* Notice extracted from xxHash homepage:
*
* xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
* It also successfully passes all tests from the SMHasher suite.
*
* Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2
* Duo @3GHz)
*
* Name Speed Q.Score Author
* xxHash 5.4 GB/s 10
* CrapWow 3.2 GB/s 2 Andrew
* MumurHash 3a 2.7 GB/s 10 Austin Appleby
* SpookyHash 2.0 GB/s 10 Bob Jenkins
* SBox 1.4 GB/s 9 Bret Mulvey
* Lookup3 1.2 GB/s 9 Bob Jenkins
* SuperFastHash 1.2 GB/s 1 Paul Hsieh
* CityHash64 1.05 GB/s 10 Pike & Alakuijala
* FNV 0.55 GB/s 5 Fowler, Noll, Vo
* CRC32 0.43 GB/s 9
* MD5-32 0.33 GB/s 10 Ronald L. Rivest
* SHA1-32 0.28 GB/s 10
*
* Q.Score is a measure of quality of the hash function.
* It depends on successfully passing SMHasher test set.
* 10 is a perfect score.
*
* A 64-bits version, named xxh64 offers much better speed,
* but for 64-bits applications only.
* Name Speed on 64 bits Speed on 32 bits
* xxh64 13.8 GB/s 1.9 GB/s
* xxh32 6.8 GB/s 6.0 GB/s
*/
#ifndef XXHASH_H
#define XXHASH_H
#include <linux/types.h>
/*-****************************
* Simple Hash Functions
*****************************/
/**
* xxh32() - calculate the 32-bit hash of the input with a given seed.
*
* @input: The data to hash.
* @length: The length of the data to hash.
* @seed: The seed can be used to alter the result predictably.
*
* Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
*
* Return: The 32-bit hash of the data.
*/
uint32_t xxh32(const void *input, size_t length, uint32_t seed);
/**
* xxh64() - calculate the 64-bit hash of the input with a given seed.
*
* @input: The data to hash.
* @length: The length of the data to hash.
* @seed: The seed can be used to alter the result predictably.
*
* This function runs 2x faster on 64-bit systems, but slower on 32-bit systems.
*
* Return: The 64-bit hash of the data.
*/
uint64_t xxh64(const void *input, size_t length, uint64_t seed);
/**
* xxhash() - calculate wordsize hash of the input with a given seed
* @input: The data to hash.
* @length: The length of the data to hash.
* @seed: The seed can be used to alter the result predictably.
*
* If the hash does not need to be comparable between machines with
* different word sizes, this function will call whichever of xxh32()
* or xxh64() is faster.
*
* Return: wordsize hash of the data.
*/
static inline unsigned long xxhash(const void *input, size_t length,
uint64_t seed)
{
#if BITS_PER_LONG == 64
return xxh64(input, length, seed);
#else
return xxh32(input, length, seed);
#endif
}
/*-****************************
* Streaming Hash Functions
*****************************/
/*
* These definitions are only meant to allow allocation of XXH state
* statically, on stack, or in a struct for example.
* Do not use members directly.
*/
/**
* struct xxh32_state - private xxh32 state, do not use members directly
*/
struct xxh32_state {
uint32_t total_len_32;
uint32_t large_len;
uint32_t v1;
uint32_t v2;
uint32_t v3;
uint32_t v4;
uint32_t mem32[4];
uint32_t memsize;
};
/**
* struct xxh32_state - private xxh64 state, do not use members directly
*/
struct xxh64_state {
uint64_t total_len;
uint64_t v1;
uint64_t v2;
uint64_t v3;
uint64_t v4;
uint64_t mem64[4];
uint32_t memsize;
};
/**
* xxh32_reset() - reset the xxh32 state to start a new hashing operation
*
* @state: The xxh32 state to reset.
* @seed: Initialize the hash state with this seed.
*
* Call this function on any xxh32_state to prepare for a new hashing operation.
*/
void xxh32_reset(struct xxh32_state *state, uint32_t seed);
/**
* xxh32_update() - hash the data given and update the xxh32 state
*
* @state: The xxh32 state to update.
* @input: The data to hash.
* @length: The length of the data to hash.
*
* After calling xxh32_reset() call xxh32_update() as many times as necessary.
*
* Return: Zero on success, otherwise an error code.
*/
int xxh32_update(struct xxh32_state *state, const void *input, size_t length);
/**
* xxh32_digest() - produce the current xxh32 hash
*
* @state: Produce the current xxh32 hash of this state.
*
* A hash value can be produced at any time. It is still possible to continue
* inserting input into the hash state after a call to xxh32_digest(), and
* generate new hashes later on, by calling xxh32_digest() again.
*
* Return: The xxh32 hash stored in the state.
*/
uint32_t xxh32_digest(const struct xxh32_state *state);
/**
* xxh64_reset() - reset the xxh64 state to start a new hashing operation
*
* @state: The xxh64 state to reset.
* @seed: Initialize the hash state with this seed.
*/
void xxh64_reset(struct xxh64_state *state, uint64_t seed);
/**
* xxh64_update() - hash the data given and update the xxh64 state
* @state: The xxh64 state to update.
* @input: The data to hash.
* @length: The length of the data to hash.
*
* After calling xxh64_reset() call xxh64_update() as many times as necessary.
*
* Return: Zero on success, otherwise an error code.
*/
int xxh64_update(struct xxh64_state *state, const void *input, size_t length);
/**
* xxh64_digest() - produce the current xxh64 hash
*
* @state: Produce the current xxh64 hash of this state.
*
* A hash value can be produced at any time. It is still possible to continue
* inserting input into the hash state after a call to xxh64_digest(), and
* generate new hashes later on, by calling xxh64_digest() again.
*
* Return: The xxh64 hash stored in the state.
*/
uint64_t xxh64_digest(const struct xxh64_state *state);
/*-**************************
* Utils
***************************/
/**
* xxh32_copy_state() - copy the source state into the destination state
*
* @src: The source xxh32 state.
* @dst: The destination xxh32 state.
*/
void xxh32_copy_state(struct xxh32_state *dst, const struct xxh32_state *src);
/**
* xxh64_copy_state() - copy the source state into the destination state
*
* @src: The source xxh64 state.
* @dst: The destination xxh64 state.
*/
void xxh64_copy_state(struct xxh64_state *dst, const struct xxh64_state *src);
#endif /* XXHASH_H */

88
config/etc/named.conf Normal file
View File

@@ -0,0 +1,88 @@
; raoult.com named.conf (gandi.net)
; SOA looks ignored when setting gandi DNS
@ 3600 IN SOA ns1.gandi.net. hostmaster.gandi.net. (
1725266688 ; serial
10800 ; refresh (3 hours)
3600 ; retry (1h)
604800 ; expire (1 week)
3600 ; minimum (1h)
)
;;; ---------------------------------- copy from here
; IP addresses
@ 3600 IN A 82.64.229.101
moreac 3600 IN A 82.67.122.150
; forgot what it is
@ 3600 IN TXT "google-site-verification=I7AEHSueTj0mpbBvL4QA3WKaPTfBiM0_6N8Var0UpU8"
; subdomains
www 3600 IN CNAME raoult.com.
home 3600 IN CNAME raoult.com.
devs 3600 IN CNAME raoult.com.
ebooks 3600 IN CNAME raoult.com.
; applications
dav 3600 IN CNAME raoult.com.
git 3600 IN CNAME raoult.com.
webtrees 3600 IN CNAME raoult.com.
; hostnames
idril 3600 IN CNAME raoult.com.
arwen 3600 IN CNAME raoult.com.
idefix 3600 IN CNAME moreac.raoult.com.
; old shared
locations 3600 IN CNAME raoult.com.
marcel 3600 IN CNAME raoult.com.
xavier 3600 IN CNAME raoult.com.
;;; ---------------------------------- end of Gandi DNS records
;;;;; default gandi.net entries
; @ 10800 IN A 217.70.184.38
; @ 10800 IN MX 10 spool.mail.gandi.net.
; @ 10800 IN MX 50 fb.mail.gandi.net.
; @ 10800 IN TXT "v=spf1 include:_mailcust.gandi.net ?all"
; _imap._tcp 10800 IN SRV 0 0 0 .
; _imaps._tcp 10800 IN SRV 0 1 993 mail.gandi.net.
; _pop3._tcp 10800 IN SRV 0 0 0 .
; _pop3s._tcp 10800 IN SRV 10 1 995 mail.gandi.net.
; _submission._tcp 10800 IN SRV 0 1 465 mail.gandi.net.
; gm1._domainkey 10800 IN CNAME gm1.gandimail.net.
; gm2._domainkey 10800 IN CNAME gm2.gandimail.net.
; gm3._domainkey 10800 IN CNAME gm3.gandimail.net.
;
; webmail 10800 IN CNAME webmail.gandi.net.
; www 10800 IN CNAME webredir.vip.gandi.net.
;;;;; old freenom
; raoult.com. 300 IN SOA ns01.freenom.com. soa.freenom.com. (
; 1725254393 ; serial
; 10800 ; refresh (3 hours)
; 3600 ; retry (1 hour)
; 604800 ; expire (1 week)
; 3600 ; minimum (1 hour)
; )
; raoult.com. 300 IN NS ns02.freenom.com.
; raoult.com. 300 IN NS ns04.freenom.com.
; raoult.com. 300 IN NS ns03.freenom.com.
; raoult.com. 300 IN NS ns01.freenom.com.
; raoult.com. 3600 IN TXT "google-site-verification=I7AEHSueTj0mpbBvL4QA3WKaPTfBiM0_6N8Var0UpU8"
;;;;; domain lists
; raoult.com
; www.raoult.com
; home.raoult.com
; arwen.raoult.com
; dav.raoult.com
; devs.raoult.com
; ebooks.raoult.com
; git.raoult.com
; locations.raoult.com
; marcel.raoult.com
; webtrees.raoult.com
; xavier.raoult.com

View File

@@ -1,50 +0,0 @@
#!/usr/bin/env bash
#
# ~/.bashrc.br.lorien - host specific initialization
#
# (C) Bruno Raoult ("br"), 2001-2023
# Licensed under the GNU General Public License v3.0 or later.
# Some rights reserved. See COPYING.
#
# You should have received a copy of the GNU General Public License along with this
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
#
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
#
# Usage: to be invoked from .bashrc.$USER
# i.e., add at the end of .bashrc.$USER:
# [ -f "$HOME/.bashrc.$USER.$(hostname)" ] && . "$HOME/.bashrc.$USER.$(hostname)"
# look for a pdf viewer
hash atril 2> /dev/null && alias acroread=atril
# mysql aliases. Will match any "[client-XXX]" lines in ~/.my.cnf
# and generate "myXXX" aliases.
if [[ -r ~/.my.cnf ]]; then
mapfile -t MYSQL_ARRAY < ~/.my.cnf
for line in "${MYSQL_ARRAY[@]}"; do
if [[ $line =~ ^\[client-(.+)\]$ ]]; then
SUFFIX="${BASH_REMATCH[1]}"
# shellcheck disable=SC2139,SC2140
alias my"$SUFFIX"="mysql --defaults-group-suffix=-$SUFFIX"
fi
done
fi
# shortcuts to commonly used directories
# alias dev="cd ~/dev/www/cf.bodi" # Clash of Clans
alias eud="cd ~/dev/eudyptula; . ./bin/ENV.sh" # Eudyptula
alias aoc="cd ~/dev/advent-of-code/2022/; . ../env.sh" # Advent of Code
alias wchess="cd ~/dev/www/com.raoult/devs/chess" # raoult.com chess
alias chess="cd ~/dev/brchess; . env.sh" # brchess
alias tools="cd ~/dev/tools" # tools
alias brlib="cd ~/dev/tools/c/brlib" # brlib dir/repo
# Indent style for emacs
# Local Variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indentation: 4
# indent-tabs-mode: nil
# End:

19
config/home/bash_profile Normal file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/env bash
#
# ~/.bash_profile - bash login script.
#
# (C) Bruno Raoult ("br"), 2024
# Licensed under the GNU General Public License v3.0 or later.
# Some rights reserved. See COPYING.
#
# You should have received a copy of the GNU General Public License along with this
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
#
# For login shells, ~/.profile is executed. Debian default one does:
# 1) source .bashrc if it exists
# 2) add "$HOME"/bin in PATH
# This imply a duplicate "$HOME/bin" in PATH, as we do everything in .bashrc.$user.
# Having this ~/.bash_profile will avoid the execution of ~/.profile
# shellcheck disable=SC1091
[ -f "$HOME/.bashrc" ] && . "$HOME/.bashrc"

View File

@@ -2,7 +2,7 @@
#
# ~/.bashrc.br - user specific initialization
#
# (C) Bruno Raoult ("br"), 2001-2023
# (C) Bruno Raoult ("br"), 2001-2024
# Licensed under the GNU General Public License v3.0 or later.
# Some rights reserved. See COPYING.
#
@@ -14,6 +14,12 @@
# Usage: to be invoked from .bashrc.
# i.e., add at the end of .bashrc:
# [ -f "$HOME/.bashrc.$USER" ] && . "$HOME/.bashrc.$USER"
#
# Debian default ~/.profile usually does:
# 1) source .bashrc if it exists
# 2) add "$HOME"/bin in PATH
# This imply a duplicate "$HOME/bin" in PATH, as we do everything here.
# Better to have a ~/.bash_profile with the lines above.
# _var_del() - remove an element from a colon-separated list.
# $1: name (reference) of a colon separated list
@@ -72,10 +78,12 @@ _var_append() {
}
# adjust PATH. Below paths will be added at beginning.
_lpath=("$HOME/bin/$(uname -s)-$(uname -m)"
"$HOME/bin"
_lpath=("$HOME/bin/$(uname -s)-$(uname -m)" # architecture specific
"$HOME/bin" # user scripts
"$HOME/.local/bin" # pip venv
#"$HOME/.cargo/bin"
"/usr/local/bin")
"/usr/local/bin"
)
# loop array in reverse order. Note: We do not test for path existence and add it
# unconditionally, to avoid automounter interference.
@@ -90,13 +98,16 @@ _var_del PATH /snap/bin
# enable core file
ulimit -Sc 102400 # in 1024 bytes, 100Mb
# ... and set PAGER to less (for man(1) and others)
# Set pager: "less" is prefered over "more".
if hash less 2>/dev/null; then
export PAGER=less
# do not clear screen after "less", exit immediately if one page only
export LESS="-XFB"
# ... and just alias more... to less ;-)
export LESS="--quit-if-one-screen --quit-at-eof --no-init"
alias more=less
else
export MORE="--exit-on-eof --silent"
export PAGER=more
alias less=more
fi
# no output split for dc and bc / make bc silent
@@ -124,7 +135,8 @@ e() {
$VISUAL "$@"
}
export -f e
if hash emacs 2>/dev/null; then
if hash emacs 2>/dev/null; then # look for Emacs...
# uncomment below to use full emacs
#export EDITOR=emacs
# ... OR: uncomment below to use emacsclient
@@ -136,8 +148,7 @@ if hash emacs 2>/dev/null; then
alias emacs="emacsclient -c"
#alias crontab="VISUAL=emacsclient crontab -e"
#alias crontab="emacs-crontab.sh"
else
# emacs clones, then vim/vi, then... whatever left.
else # ... or clones, vim/vi, etc...
_VISUALS=(zile jed mg e3em vim vi nano ed)
for e in "${_VISUALS[@]}"; do
@@ -150,6 +161,15 @@ else
fi
export EDITOR=$VISUAL
for _pdfviewer in atril qpdfview; do # look for a pdf viewer
if hash "$_pdfviewer" 2>/dev/null; then
# shellcheck disable=SC2139
alias acroread="$_pdfviewer"
break
fi
done
unset _pdfviewer
# append to the history file, don't overwrite it
shopt -s histappend
# write history after each command
@@ -173,7 +193,7 @@ export QUOTING_STYLE=literal
# avoid these stupid systemd defaults (horizontal scroll and pager)
alias systemctl="systemctl --no-pager --full"
# aliases for ls and history
# aliases/functions for usual commands (ls, history, grep...)
alias l='ls -F'
alias ls='ls -F'
alias l1='ls -1F'
@@ -207,6 +227,10 @@ alias hl="history 25" # long
alias hll="history 100" # very long
alias hlll="history" # all history
alias grep='grep --color=auto' # add colors to grep
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
# user temp directory
export USERTMP=~/tmp
@@ -245,6 +269,19 @@ rehash() {
alias trans="trans.sh"
alias rtrans="trans.sh -fen -tfr"
# easy directory sync (remove source trailing slash)
syncdir() {
local -a opts=(--archive --hard-links --one-file-system --itemize-changes --delete)
local src="$1" dst="$2"
case "$src" in
*[!/]*/)
src=${src%"${src##*[!/]}"};;
*[/])
src="/";;
esac
rsync "${opts[@]}" "$src" "$dst"
}
# host specific initialization
# shellcheck disable=SC1090
[ -f "$HOME/.bashrc.$USER.$(hostname)" ] && . "$HOME/.bashrc.$USER.$(hostname)"

View File

@@ -0,0 +1,80 @@
#!/usr/bin/env bash
#
# ~/.bashrc.br.eowyn - host specific initialization
#
# (C) Bruno Raoult ("br"), 2001-2024
# Licensed under the GNU General Public License v3.0 or later.
# Some rights reserved. See COPYING.
#
# You should have received a copy of the GNU General Public License along with this
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
#
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
#
# Usage: to be invoked from .bashrc.$USER
# i.e., add at the end of .bashrc.$USER:
# [ -f "$HOME/.bashrc.$USER.$(hostname)" ] && . "$HOME/.bashrc.$USER.$(hostname)"
# mysql aliases. Will match any "[client-XXX]" lines in ~/.my.cnf
# and generate "myXXX" aliases.
if [[ -r ~/.my.cnf ]]; then
mapfile -t MYSQL_ARRAY < ~/.my.cnf
for line in "${MYSQL_ARRAY[@]}"; do
if [[ $line =~ ^\[client-(.+)\]$ ]]; then
SUFFIX="${BASH_REMATCH[1]}"
# shellcheck disable=SC2139,SC2140
alias my"$SUFFIX"="mysql --defaults-group-suffix=-$SUFFIX"
fi
done
fi
# shortcuts to commonly used directories/projects
# _vardir() - define common dirs vars & aliases
# $1: name variable to set
# $2: name of alias to define
# $3: script to source (relative to $2). '-': no script, '+': './script/env.sh'
# $4: project path
#
# _vardir() sets variable with $1 name to $4, and an alias with $2 name.
# The alias, when invoked, will:
# (1) change working directory to $1
# (2) source $3 when $3 is not '-'. $3 path can be relative (preferred), or
# absolute. If $3 is "+", it will default to "scripts/env.sh".
#
# Examples:
# _vardir MYDIR mydir - ~/foo/mydirprj
_vardir() {
local _v="$1" _a="$2" _s="$3" _p="$4"
if [[ ! -d $_p ]]; then
printf "ignored project: %s\n" "$_p"
return 0
fi
local _x="cd $_p"
export "$_v"="$_p"
case "$_s" in
-) ;;
+) _s="scripts/env.sh" ;&
*) if [[ -r "$_p/$_s" ]]; then
_x+="; . $_s"
else
printf "%s: ignored.\n" "$_p/$_s"
fi
esac
# shellcheck disable=SC2139
alias "$_a"="$_x"
}
_vardir CHESS chess + ~/dev/brchess # brchess
_vardir ENGINES engines - ~/dev/chess-engines # chess engines
_vardir TOOLS tools - ~/dev/tools # tools
_vardir BRLIB brlib - ~/dev/brlib # brlib
_vardir DEV dev - ~/dev # dev
# Indent style for emacs
# Local Variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indentation: 4
# indent-tabs-mode: nil
# End:

View File

@@ -0,0 +1,83 @@
#!/usr/bin/env bash
#
# ~/.bashrc.br.lorien - host specific initialization
#
# (C) Bruno Raoult ("br"), 2001-2024
# Licensed under the GNU General Public License v3.0 or later.
# Some rights reserved. See COPYING.
#
# You should have received a copy of the GNU General Public License along with this
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
#
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
#
# Usage: to be invoked from .bashrc.$USER
# i.e., add at the end of .bashrc.$USER:
# [ -f "$HOME/.bashrc.$USER.$(hostname)" ] && . "$HOME/.bashrc.$USER.$(hostname)"
# mysql aliases. Will match any "[client-XXX]" lines in ~/.my.cnf
# and generate "myXXX" aliases.
if [[ -r ~/.my.cnf ]]; then
mapfile -t MYSQL_ARRAY < ~/.my.cnf
for line in "${MYSQL_ARRAY[@]}"; do
if [[ $line =~ ^\[client-(.+)\]$ ]]; then
SUFFIX="${BASH_REMATCH[1]}"
# shellcheck disable=SC2139,SC2140
alias my"$SUFFIX"="mysql --defaults-group-suffix=-$SUFFIX"
fi
done
fi
# shortcuts to commonly used directories/projects
# _vardir() - define common dirs vars & aliases
# $1: name variable to set
# $2: name of alias to define
# $3: script to source (relative to $2). '-': no script, '+': './script/env.sh'
# $4: project path
#
# _vardir() sets variable with $1 name to $4, and an alias with $2 name.
# The alias, when invoked, will:
# (1) change working directory to $1
# (2) source $3 when $3 is not '-'. $3 path can be relative (preferred), or
# absolute. If $3 is "+", it will default to "scripts/env.sh".
#
# Examples:
# _vardir MYDIR mydir - ~/foo/mydirprj
_vardir() {
local _v="$1" _a="$2" _s="$3" _p="$4"
if [[ ! -d $_p ]]; then
printf "ignored project: %s\n" "$_p"
return 0
fi
local _x="cd $_p"
export "$_v"="$_p"
case "$_s" in
-) ;;
+) _s="scripts/env.sh" ;&
*) if [[ -r "$_p/$_s" ]]; then
_x+="; . $_s"
else
printf "%s: ignored.\n" "$_p/$_s"
fi
esac
# shellcheck disable=SC2139
alias "$_a"="$_x"
}
_vardir AOC aoc + ~/dev/advent-of-code # Advent of code
_vardir WCHESS wchess - ~/dev/www/crd/chess # raoult.com chess
_vardir CHESS chess + ~/dev/brchess # brchess
_vardir ENGINES engines - ~/dev/chess-engines # chess engines
_vardir TOOLS tools - ~/dev/tools # tools
_vardir BRLIB brlib - ~/dev/brlib # brlib
_vardir EUD eud + ~/dev/eudyptula # eudyptula
_vardir DEV dev - ~/dev # dev
# Indent style for emacs
# Local Variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indentation: 4
# indent-tabs-mode: nil
# End:

211
config/home/bashrc.root Normal file
View File

@@ -0,0 +1,211 @@
#!/usr/bin/env bash
#
# ~/.bashrc.root - root bash startup
#
# (C) Bruno Raoult ("br"), 2001-2024
# Licensed under the GNU General Public License v3.0 or later.
# Some rights reserved. See COPYING.
#
# You should have received a copy of the GNU General Public License along with this
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
#
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
#
# Usage: to be invoked from .bashrc.
# i.e., add at the end of .bashrc:
# [ -f "$HOME/.bashrc.$USER" ] && . "$HOME/.bashrc.$USER"
#
# Debian default ~/.profile usually does:
# 1) source .bashrc if it exists
# 2) add "$HOME"/bin in PATH
# This imply a duplicate "$HOME/bin" in PATH, as we do everything here.
# Better to have a ~/.bash_profile with the lines above.
# _var_del() - remove an element from a colon-separated list.
# $1: name (reference) of a colon separated list
# $2: element to remove (string)
#
# _var_del() removes every occurrence of $2, if there are more than 1,
# and leaves $1 unchanged if $2 is not present.
#
# Example:
# With VAR's value being "foo:bar:quax:bar". Using "_var_del VAR bar" will
# leave VAR with the value "foo:quax".
_var_del() {
local -n _p_del=$1
local _l=":$_p_del:"
while [[ $_l =~ :$2: ]]; do
_l=${_l//:$2:/:}
done
_l=${_l%:}
_l=${_l#:}
_p_del="$_l"
}
# _var_prepend() - prepend element to colon-separated variable.
# $1: variable name (reference)
# $2: element to add (string)
#
# Any occurrence of $2 in $1 is first removed, then $2 is added at $1 beginning.
#
# Example:
# With VAR's value being "foo:bar:quax:bar". Using "_var_prepend VAR bar"
# will leave VAR with the value "bar:foo:quax".
_var_prepend() {
local -n _p_prepend=$1
_var_del _p_prepend "$2"
[[ -z $_p_prepend ]] && _p_prepend="$2" && return
_p_prepend="$2:$_p_prepend"
}
# _var_append() - append element to colon-separated variable.
# $1: variable name (reference)
# $2: element to add (string)
#
# Any occurrence of $2 in $1 is first removed, then $2 is added at $1 end.
#
# Example:
# With VAR's value being "foo:bar:quax:bar". Using "_var_append VAR bar"
# will leave VAR with the value "foo:quax:bar".
_var_append() {
local -n _p_append=$1
_var_del _p_append "$2"
[[ -z $_p_append ]] && _p_append="$2" && return
_p_append="$_p_append:$2"
}
# adjust PATH. Below paths will be added at beginning.
_lpath=("$HOME/bin/$(uname -s)-$(uname -m)"
"$HOME/bin"
"/usr/local/bin")
# loop array in reverse order. Note: We do not test for path existence and add it
# unconditionally, to avoid automounter interference.
for (( _i = ${#_lpath[@]} - 1; _i >= 0; --_i )); do
_var_prepend PATH "${_lpath[_i]}"
done
unset _lpath
# enable core file
ulimit -HSc 102400 # in 1024 bytes - Really cannot use KiB :-)
# ... and set PAGER to less (for man(1) and others)
if hash less 2>/dev/null; then
export PAGER=less
# do not clear screen after "less", exit immediately if one page only
export LESS="-XFB"
# ... and just alias more... to less ;-)
alias more=less
fi
# no output split for dc and bc / make bc silent
export DC_LINE_LENGTH=0
export BC_LINE_LENGTH=0
export BC_ENV_ARGS=--quiet
# both ubuntu and debian assume we want colors if TERM contains "color"
# this is surely not true, as TERM is often forced by terminal emulator
# shellcheck disable=SC2154
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
# trim prompt path
export PROMPT_DIRTRIM=3
# find a suitable editor
e() {
$VISUAL "$@"
}
export -f e
# no Emacs for root
# emacs clones, then vim/vi, then... whatever left.
_VISUALS=(zile mg jed vim vi nano ed)
for e in "${_VISUALS[@]}"; do
if hash "$e" 2>/dev/null; then
export VISUAL="$e"
break
fi
done
unset _VISUALS
export EDITOR=$VISUAL
# append to the history file, don't overwrite it
shopt -s histappend
# write history after each command
export PROMPT_COMMAND="history -a"
# Add timestamp in history
export HISTTIMEFORMAT="%d/%m %H:%M "
# ignore history dups, delete all previous dups
export HISTCONTROL="ignorespace:ignoredups:erasedups"
# ignore these in history
export HISTIGNORE="history *:h:hl:hll:hlll"
# history size
HISTSIZE=5000
HISTFILESIZE=5000
# remove new stupid Debian "ls" quoting, and colors...
# Many complains, one of them:
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=813164#226
export QUOTING_STYLE=literal
[[ -v BASH_ALIASES[ls] ]] && unalias ls
# aliases/functions for ls and history
alias l='ls -F'
alias ls='ls -F'
alias l1='ls -1F'
alias la='ls -AF'
alias ll='ls -lF'
alias lla='ls -lAF'
alias ldl='ls -l | grep ^d'
[[ -v BASH_ALIASES[lrt] ]] && unalias lrt
lrt() {
local -i _l=20
if (( $# > 0 )) && [[ $1 =~ [[:digit:]]+ ]]; then
_l="$1"
shift
fi
# shellcheck disable=2012
ls -lrt "${1:-.}" | tail -"$_l"
}
[[ -v BASH_ALIASES[lart] ]] && unalias lart
lart() {
local -i _l=20
if (( $# > 0 )) && [[ $1 =~ [[:digit:]]+ ]]; then
_l="$1"
shift
fi
# shellcheck disable=2012
ls -laFrt "${1:-.}" | tail -"$_l"
}
alias h="history 10" # short
alias hl="history 25" # long
alias hll="history 100" # very long
alias hlll="history" # all history
alias grep='grep --color=auto' # add colors to grep
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
# misc aliases
alias fuck='sudo $(history -p \!\!)'
alias diff='diff -u'
# Indent style for emacs
# Local Variables:
# mode: shell-script
# sh-basic-offset: 4
# sh-indentation: 4
# indent-tabs-mode: nil
# comment-column: 32
# End:

View File

@@ -1,7 +1,7 @@
;;;; ~/.Emacs.d/init.el
;;;;
;;;; emacs configuration
;;;; br, 2010-2023
;;;; br, 2010-2024
;;;;
;;;; all personal variables/defun are prefixed with "my/".
;;
@@ -15,6 +15,8 @@
;; (require 'use-package)
(package-initialize)
(setq use-package-always-ensure t)
;; (setq package-check-signature nil)
(use-package delight :ensure t)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
;;(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/"))
@@ -34,8 +36,7 @@
"Directory where to store all temp and backup files.")
(setq backup-directory (concat my/emacs-tmpdir "/backups/")
save-directory (concat my/emacs-tmpdir "/autosave/")
auto-save-list-file-prefix (concat my/emacs-tmpdir "/autosave-list/")
)
auto-save-list-file-prefix (concat my/emacs-tmpdir "/autosave-list/"))
;; create dirs if necessary
(dolist (dir (list backup-directory save-directory auto-save-list-file-prefix))
@@ -76,6 +77,8 @@
(defun risky-local-variable-p (sym &optional _ignored) "Zoba SYM." nil)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; swap modifier keysyms (japanese keyboard)
;; Done in .xmodmap
;;
;; windows key (super) becomes hyper
;;(setq x-super-keysym 'hyper)
;; alt key (meta) becomes super
@@ -254,23 +257,33 @@ Return new LIST-VAR value."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ggtags
(use-package ggtags
:ensure t
:diminish ggtags-mode
:diminish "gg"
:disabled t
:defer t
;; :defer t
:after cc-mode
:init
(setq ggtags-global-window-height 28
ggtags-enable-navigation-keys nil)
(after cc-mode (add-hook 'c-mode-common-hook #'ggtags-mode))
(add-hook 'c-mode-common-hook
(lambda ()
(when (derived-mode-p 'c-mode 'c++-mode 'java-mode)
(ggtags-mode 1))))
;;(after cc-mode (add-hook 'c-mode-common-hook #'ggtags-mode))
:config
(bind-keys :map ggtags-mode-map
("C-c g s" . ggtags-find-other-symbol)
("C-c g h" . ggtags-view-tag-history)
("C-c g r" . ggtags-find-reference)
("C-c g f" . ggtags-find-file)
("C-c g c" . ggtags-create-tags)
("C-c g u" . ggtags-update-tags)
;;("C-c g s" . ggtags-find-other-symbol)
;;("C-c g h" . ggtags-view-tag-history)
;;("C-c g r" . ggtags-find-reference)
;;("C-c g f" . ggtags-find-file)
;;("C-c g c" . ggtags-create-tags)
;;("C-c g u" . ggtags-update-tags)
("H-g s" . ggtags-find-other-symbol)
("H-g h" . ggtags-view-tag-history)
("H-g r" . ggtags-find-reference)
("H-g f" . ggtags-find-file)
("H-g c" . ggtags-create-tags)
("H-g u" . ggtags-update-tags)
("M-," 'pop-tag-mark)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; projectile
@@ -278,6 +291,7 @@ Return new LIST-VAR value."
(use-package projectile
;;:diminish projectile-mode
:diminish " prj"
;; :delight
:ensure t
:config
;;(define-key projectile-mode-map (kbd "s-p") 'projectile-command-map)
@@ -287,7 +301,9 @@ Return new LIST-VAR value."
;;projectile-indexing-method 'alien ;; does not use ".projectile"
projectile-indexing-method 'hybrid
;;projectile-indexing-method 'native
projectile-completion-system 'default)
projectile-completion-system 'auto
projectile-tags-backend 'ggtags)
(add-to-list 'projectile-globally-ignored-files "*.png")
(projectile-mode +1))
@@ -301,8 +317,10 @@ Return new LIST-VAR value."
:config
(setq magit-delete-by-moving-to-trash nil
magit-clone-default-directory "~/dev/")
(magit-auto-revert-mode -1))
(magit-auto-revert-mode -1)
:bind
(("C-c g" . magit-file-dispatch)
("C-x g" . magit-status)))
(use-package git-gutter
:diminish
@@ -340,6 +358,9 @@ Return new LIST-VAR value."
tramp-verbose 1)
;; (customize-set-variable 'tramp-syntax 'simplified)
;; Emacs 29.1 ?
;;(autoload #'tramp-register-crypt-file-name-handler "tramp-crypt")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; conf mode
;; strangely ".cnf" is not here...
(use-package conf-mode
@@ -428,12 +449,23 @@ Return new LIST-VAR value."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Some useful setups
;; mouse
;; does not change point when getting focus - DOES NOT WORK
;;x-mouse-click-focus-ignore-position t
;; (setq x-mouse-click-focus-ignore-position t)
;;focus-follows-mouse nil ; must reflect WM settings
;;mouse-autoselect-window nil ; pointer does not select window
(global-set-key (kbd "C-h c") 'describe-char)
(global-set-key (kbd "C-x 4 C-b") 'switch-to-buffer-other-window)
(global-unset-key [mode-line mouse-3]) ; disabble annoying modeline mouse-3
;; compilation buffer in different frame
;; https://emacs.stackexchange.com/a/21393/23591
;; (push "*compilation*" special-display-buffer-names)
;; https://emacs.stackexchange.com/a/75534/23591
(add-to-list 'display-buffer-alist
(cons (rx string-start "*compilation*" string-end)
(cons 'display-buffer-reuse-window
'((reusable-frames . visible)
(inhibit-switch-frames . nil)))))
;; next example maps C-x C-x to the same as C-c
;; (global-set-key (kbd "C-x C-x") (lookup-key global-map (kbd "C-c")))
@@ -460,7 +492,7 @@ Return new LIST-VAR value."
tab-width 2 ; default tab width
)
(setq-default indent-tabs-mode nil)
(setq-default indent-tabs-mode nil) ; no tabs
(icomplete-mode 0) ; minibuffer completion
; soooo sloooow
@@ -476,7 +508,10 @@ Return new LIST-VAR value."
(setq display-time-24hr-format t) ; time format
(display-time-mode 0) ; disable time in the mode-line
(defalias 'yes-or-no-p 'y-or-n-p) ; just 'y' or 'n' instead of yes/no
(if (< emacs-major-version 29) ; just 'y' or 'n' instead of yes/no
(defalias 'yes-or-no-p 'y-or-n-p)
(setopt use-short-answers t))
(setq duplicate-line-final-position -1) ; point on last new line
(mouse-avoidance-mode 'exile) ; Avoid collision of mouse with point
@@ -655,6 +690,7 @@ point reaches the beginning or end of the buffer, stop there."
(global-set-key (kbd "M-u") 'my/upcase-word)
(global-set-key (kbd "M-l") 'my/downcase-word)
(global-set-key (kbd "H-y") 'duplicate-dwim)
;; rewrite comment-kill to avoid filling kill-ring
;; From: https://emacs.stackexchange.com/a/5445/23591
@@ -710,6 +746,25 @@ in whole buffer. With neither, delete comments on current line."
(while (re-search-forward "\\(^[[:space:]\n]+\\)\n" nil t)
(replace-match "\n"))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; multiple cursors
(use-package multiple-cursors
:bind
(("C-c m t" . mc/mark-all-like-this)
("C-c m m" . mc/mark-all-like-this-dwim)
("C-c m l" . mc/edit-lines)
("C-c m e" . mc/edit-ends-of-lines)
("C-c m a" . mc/edit-beginnings-of-lines)
("C-c m n" . mc/mark-next-like-this)
("C-c m p" . mc/mark-previous-like-this)
("C-c m s" . mc/mark-sgml-tag-pair)
("C-c m d" . mc/mark-all-like-this-in-defun)
("C->" . mc/mark-next-like-this)
("C-<" . mc/mark-previous-like-this)
("C-S-<mouse-1>" . mc/add-cursor-on-click)
("C-M-m" . mc/mark-all-dwim)))
(use-package phi-search)
(use-package phi-search-mc :config (phi-search-mc/setup-keys))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; shell, eshell modes
;; will tell e-shell to run in visual mode
'(eshell-visual-commands
@@ -727,7 +782,7 @@ in whole buffer. With neither, delete comments on current line."
"Switch the buffers between the two last frames."
(interactive)
(let ((this-frame-buffer nil)
(other-frame-buffer nil))
(other-frame-buffer nil))
(setq this-frame-buffer (car (frame-parameter nil 'buffer-list)))
(other-frame 1)
(setq other-frame-buffer (car (frame-parameter nil 'buffer-list)))
@@ -756,19 +811,19 @@ in whole buffer. With neither, delete comments on current line."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vc-mode modeline
;; inspired from:
;; https://emacs.stackexchange.com/questions/10955
(advice-add #'vc-git-mode-line-string :filter-return #'my-replace-git-status)
(defun my-replace-git-status (tstr)
"Replace git `variable:vc-mode' string, for a modified icon followed by TSTR without \"git\"."
(advice-add #'vc-git-mode-line-string :filter-return #'my/replace-git-status)
(defun my/replace-git-status (tstr)
"Replace git `variable:vc-mode' string with a UTF8 symbol followed by TSTR."
(let* ((tstr (replace-regexp-in-string "Git" "" tstr))
(first-char (substring tstr 0 1))
(rest-chars (substring tstr 1)))
(cond
((string= ":" first-char) ; Modified
(replace-regexp-in-string "^:" "" tstr))
(replace-regexp-in-string "^:" "" tstr))
((string= "-" first-char) ; No change
(replace-regexp-in-string "^-" "" tstr))
(replace-regexp-in-string "^-" "" tstr))
((string= "@" first-char) ; Added
(replace-regexp-in-string "^@" "️✑" tstr))
(replace-regexp-in-string "^@" "" tstr))
(t tstr))))
(setf mode-line-modes
@@ -842,41 +897,34 @@ in whole buffer. With neither, delete comments on current line."
(global-set-key (kbd "C-x w") 'compare-windows)
;; multiple cursors
(global-set-key (kbd "C->") 'mc/mark-next-like-this)
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
(global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this)
(global-set-key (kbd "C-S-<mouse-1>") 'mc/add-cursor-on-click)
(global-set-key (kbd "C-M-m") 'mc/mark-all-dwim)
;; as dot-mode uses <insert>, we allow overwrite-mode with S-<insert>
(global-set-key (kbd "S-<insert>") 'overwrite-mode)
(global-set-key (kbd "C-x g") 'magit-status)
;; (global-set-key (kbd "s-SPC") 'delete-blank-lines)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; define my own keymap (s-c)
;; first, define a keymap, with Super-c as prefix.
(defvar my/keys-mode-map (make-sparse-keymap)
"Keymap for my/keys-mode.")
;; (defvar my/keys-mode-map (make-sparse-keymap)
;; "Keymap for my/keys-mode.")
(defvar my/keys-mode-prefix-map (lookup-key global-map (kbd "s-c"))
"Keymap for custom key bindings starting with s-c prefix.")
;; (defvar my/keys-mode-prefix-map (lookup-key global-map (kbd "s-c"))
;; "Keymap for custom key bindings starting with s-c prefix.")
;; (define-key my/keys-mode-map (kbd "s-c") my/keys-mode-prefix-map)
;; ;; (define-key my/keys-mode-map (kbd "s-c") my/keys-mode-prefix-map)
(define-minor-mode my/keys-mode
"A minor mode for custom key bindings."
:lighter "s-c"
:keymap 'my/keys-mode-map
:global t)
;; (define-minor-mode my/keys-mode
;; "A minor mode for custom key bindings."
;; :lighter "s-c"
;; :keymap 'my/keys-mode-map
;; :global t)
(defun my/prioritize-keys
(file &optional noerror nomessage nosuffix must-suffix)
"Try to ensure that custom key bindings always have priority."
(unless (eq (caar minor-mode-map-alist) 'my/keys-mode)
(let ((my/keys-mode-map (assq 'my/keys-mode minor-mode-map-alist)))
(assq-delete-all 'my/keys-mode minor-mode-map-alist)
(add-to-list 'minor-mode-map-alist my/keys-mode-map))))
;; (defun my/prioritize-keys
;; (file &optional noerror nomessage nosuffix must-suffix)
;; "Try to ensure that custom key bindings always have priority."
;; (unless (eq (caar minor-mode-map-alist) 'my/keys-mode)
;; (let ((my/keys-mode-map (assq 'my/keys-mode minor-mode-map-alist)))
;; (assq-delete-all 'my/keys-mode minor-mode-map-alist)
;; (add-to-list 'minor-mode-map-alist my/keys-mode-map))))
(advice-add 'load :after #'my/prioritize-keys)
;; (advice-add 'load :after #'my/prioritize-keys)
;;(global-set-key (kbd "C-c t") #'make-temp-buffer)
;;(define-key my/keys-mode-prefix-map (kbd "r b") #'revert-buffer)
@@ -891,11 +939,13 @@ in whole buffer. With neither, delete comments on current line."
:diminish helm-mode
:init
;;(progn
;;(require 'helm-config)
;;(require 'helm-autoloads)
;; (require 'helm-config)
;; (require 'helm-autoloads)
(require 'pcomplete)
(require 'helm-projectile)
;; (require 'tramp)
(setq
helm-candidate-number-limit 100
;; From https://gist.github.com/antifuchs/9238468
helm-split-window-inside-p t ; open helm buffer in current window
@@ -917,6 +967,8 @@ in whole buffer. With neither, delete comments on current line."
helm-scroll-amount 8 ; scroll 8 lines other window M-<NEXT>
helm-ff-file-name-history-use-recentf t
helm-move-to-line-cycle-in-source nil
;; helm-ff-auto-update-initial-value nil
helm-echo-input-in-header-line t) ; ??
;;)
(helm-mode)
@@ -941,10 +993,19 @@ in whole buffer. With neither, delete comments on current line."
("<tab>" . helm-execute-persistent-action)
("C-i" . helm-execute-persistent-action) ; make TAB works in terminal
("C-z" . helm-select-action) ; list actions using C-z
;; bookmarks
))
)
;;("<left>" . helm-previous-source)
;;("<right>" . helm-next-source)
;;:map helm-imenu-map
;;("<left>" . helm-previous-source)
;;("<right>" . helm-next-source)
;;:map helm-find-files-map
;;("<left>" . helm-previous-source)
;;("<right>" . helm-next-source))
:bind*
(:map helm-find-files-map
("<left>" . helm-previous-source)
("<right>" . helm-next-source)))
(use-package helm-swoop
:bind
@@ -995,27 +1056,59 @@ in whole buffer. With neither, delete comments on current line."
;;(define-key whole-line-or-region-local-mode-map [remap uncomment-region] nil)
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; undo tree
(use-package undo-tree
:diminish undo-tree-mode
:defer t
:init
(progn
(defalias 'redo 'undo-tree-redo)
(defalias 'undo 'undo-tree-undo)
(global-undo-tree-mode 1))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; vundo / undo-tree / winner
;; vundo config from :
;; https://www.reddit.com/r/emacs/comments/txwwfi/vundo_is_great_visual_undotree_for_emacs28/
(use-package vundo
:commands (vundo)
:config
(progn
(setq undo-tree-visualizer-timestamps t
undo-tree-visualizer-diff t
undo-tree-enable-undo-in-region t
;;undo-tree-auto-save-history t
)
(let ((undo-dir (concat my/emacs-tmpdir "/undo-tree/")))
(setq undo-tree-history-directory-alist
`(("." . ,undo-dir)))
(unless (file-exists-p undo-dir)
(make-directory undo-dir t)))))
;; Take less on-screen space.
(setq vundo-compact-display t)
;; Better contrasting highlight.
(custom-set-faces
'(vundo-node ((t (:foreground "#808080"))))
'(vundo-stem ((t (:foreground "#808080"))))
'(vundo-highlight ((t (:foreground "#FFFF00")))))
;; Use `HJKL` VIM-like motion, also Home/End to jump around.
;; (define-key vundo-mode-map (kbd "l") #'vundo-forward)
(define-key vundo-mode-map (kbd "<right>") #'vundo-forward)
;; (define-key vundo-mode-map (kbd "h") #'vundo-backward)
(define-key vundo-mode-map (kbd "<left>") #'vundo-backward)
;; (define-key vundo-mode-map (kbd "j") #'vundo-next)
(define-key vundo-mode-map (kbd "<down>") #'vundo-next)
;; (define-key vundo-mode-map (kbd "k") #'vundo-previous)
(define-key vundo-mode-map (kbd "<up>") #'vundo-previous)
(define-key vundo-mode-map (kbd "<home>") #'vundo-stem-root)
(define-key vundo-mode-map (kbd "<end>") #'vundo-stem-end)
(define-key vundo-mode-map (kbd "q") #'vundo-confirm)
(define-key vundo-mode-map (kbd "C-g") #'vundo-quit)
(define-key vundo-mode-map (kbd "RET") #'vundo-confirm))
(global-set-key (kbd "C-x u") 'vundo)
;; (use-package undo-tree
;; :diminish undo-tree-mode
;; :defer t
;; :init
;; (progn
;; (defalias 'redo 'undo-tree-redo)
;; (defalias 'undo 'undo-tree-undo)
;; (global-undo-tree-mode 1))
;; :config
;; (progn
;; (setq undo-tree-visualizer-timestamps t
;; undo-tree-visualizer-diff t
;; undo-tree-enable-undo-in-region t
;; ;;undo-tree-auto-save-history t
;; )
;; (let ((undo-dir (concat my/emacs-tmpdir "/undo-tree/")))
;; (setq undo-tree-history-directory-alist
;; `(("." . ,undo-dir)))
;; (unless (file-exists-p undo-dir)
;; (make-directory undo-dir t)))))
;; useful to come back to working window after a buffer has popped up
;; C-c <left> to come back
@@ -1040,7 +1133,8 @@ in whole buffer. With neither, delete comments on current line."
;; ([return] . nil)
("TAB" . company-complete-selection)
;; ([tab] . company-complete-selection)
("<right>" . company-complete-common))
;;("<right>" . company-complete-common)
)
:config
;; Too slow !
;; (global-company-mode 1)
@@ -1170,13 +1264,19 @@ in whole buffer. With neither, delete comments on current line."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; makefile mode
(defun my/makefile-mode-hook ()
"X br text mode hook."
(message "entering Makefile-mode")
"X br makefile mode hook."
;; (message "entering Makefile-mode")
(setq indent-tabs-mode t
tab-width 4
comment-column 60))
tab-width 8
comment-column 60
comment-fill-column 120)
;;(defadvice comment-indent (around indent-to activate)
;; "Disable indent-tab-mode when indenting comment."
;; (lambda (fun &rest args) (let (indent-tabs-mode) (apply fun args))))
(add-hook 'text-mode-hook 'my/text-mode-hook)
)
(add-hook 'makefile-mode-hook 'my/makefile-mode-hook)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org mode
;; mediawiki export
@@ -1333,7 +1433,15 @@ in whole buffer. With neither, delete comments on current line."
comment-auto-fill-only-comments nil
comment-style 'extra-line))
(add-hook 'c-mode-hook 'my/c-style)
(use-package cc-mode
:ensure nil
:config
(add-hook 'c-mode-common-hook
(lambda ()
;;(when (derived-mode-p 'c-mode 'c++-mode 'java-mode 'asm-mode)
(when (derived-mode-p 'c-mode)
(ggtags-mode 1))))
(add-hook 'c-mode-hook 'my/c-style))
;;;;;;;;;;;;; linux kernel style
(defun c-lineup-arglist-tabs-only (ignored)
@@ -2112,8 +2220,8 @@ The output will appear in the buffer *PHP*."
;;; c-mode
(sp-with-modes '(c-mode c++-mode)
(sp-local-pair "{" nil :post-handlers '(("||\n[i]" "RET")))
(sp-local-pair "/*" "*/" :post-handlers '((" | " "SPC")
("* ||\n[i]" "RET"))))
(sp-local-pair "/*" "*/" :post-handlers '(("| " "SPC")
("* ||\n[i]" "RET"))))
;;; markdown-mode
(sp-with-modes '(markdown-mode gfm-mode rst-mode)
(sp-local-pair "*" "*" :bind "C-*")
@@ -2146,7 +2254,7 @@ The output will appear in the buffer *PHP*."
'sh-mode-hook
(lambda ()
(setq indent-tabs-mode nil
tab-width 4
tab-width 4
sh-basic-offset 4
comment-column 50
comment-auto-fill-only-comments t
@@ -2171,7 +2279,7 @@ The output will appear in the buffer *PHP*."
;;lsp-enable-on-type-formatting nil
lsp-enable-snippet nil
lsp-enable-symbol-highlighting t
lsp-lens-enable t
lsp-lens-enable nil
lsp-headerline-breadcrumb-enable t
lsp-enable-indentation nil
lsp-enable-on-type-formatting nil
@@ -2180,6 +2288,8 @@ The output will appear in the buffer *PHP*."
lsp-modeline-code-actions-enable t
lsp-modeline-code-actions-segments '(count icon name)
lsp-signature-render-documentation t)
;;(define-key lsp-mode-map (kbd "<mouse-3>") nil)
;;(define-key lsp-mode-map (kbd "C-S-<mouse-3>") 'lsp-mouse-click)
:hook
((sh-mode . lsp-deferred)
;;(c-mode-common . lsp-deferred)
@@ -2189,14 +2299,22 @@ The output will appear in the buffer *PHP*."
:ensure t
;;:diminish
:config
(setq ; lsp-ui-doc-show-with-cursor t
; lsp-ui-doc-show-with-mouse t
lsp-ui-sideline-enable t
lsp-ui-sideline-show-code-actions t
lsp-ui-sideline-enable t
(setq lsp-ui-doc-show-with-cursor t
lsp-ui-doc-show-with-mouse nil ; breaks isearch
lsp-ui-sideline-enable nil ; too messy
lsp-ui-sideline-show-hover t
lsp-ui-sideline-enable t
lsp-ui-doc-enable nil)
lsp-ui-sideline-show-symbol t
lsp-ui-sideline-show-code-actions t
;; lsp-ui-doc-enable nil
;; TRIED 2024/02/26
lsp-ui-doc-enable t
lsp-ui-doc-max-width 80
lsp-ui-doc-max-height 20
lsp-ui-doc-include-signature t ; type signature in doc
lsp-ui-doc-enhanced-markdown t ; looks b0rken (lists...)
lsp-ui-doc-position 'top ; top/bottom/at-point
lsp-ui-doc-alignment 'window)
:commands
(lsp-ui-mode)
@@ -2219,7 +2337,7 @@ The output will appear in the buffer *PHP*."
:diminish " ccls"
:init
(setq ccls-initialization-options
'(:index (:comments 2) :completion (:detailedLabel t)))
'(:index (:comments 2) :completion (:detailedLabel t)))
(setq-default flycheck-disabled-checkers '(c/c++-clang c/c++-cppcheck c/c++-gcc))
(setq ccls-sem-highlight-method 'font-lock)
;; alternatively,
@@ -2318,11 +2436,22 @@ at beginning and end of lines."
(while (re-search-forward "[ \t]+" nil t)
(replace-match " "))
;; remove spaces at lines beginning
(goto-char (point-min))
(while (re-search-forward "^[ \t]+" nil t)
(replace-match ""))
;;(goto-char (point-min))
;;(while (re-search-forward "^[ \t]+" nil t)
;; (replace-match ""))
;; remove spaces at line start/end
(delete-trailing-whitespace))))
;(delete-trailing-whitespace)
)))
(defun my/align-c-array (beg end)
"Align array declaration on commas between BEG and END."
(interactive "r")
(save-excursion
(save-restriction
(narrow-to-region beg end)
(my/trim-spaces (point-min) (point-max))
(align-regexp (point-min) (point-max) "\\(\\s-[[:alnum:]-_]+,\\)" -1 1 t)
(indent-region (point-min) (point-max) nil))))
(defun my/align (beg end)
"Align columns with spaces."

View File

@@ -36,16 +36,18 @@
(defconst my/loaded-files-at-startup
(list
"~/dev/brchess/Makefile"
"~/dev/tools/c/Makefile"
"~/org/boot-disk.org"
"~/org/beaglebone-buster-setup.org"
"~/dev/brlib/Makefile"
;;"~/org/boot-disk.org"
;;"~/org/beaglebone-buster-setup.org"
;;"~/dev/www/cf.bodi/sql/coc.sql"
;;"~/dev/www/cf.bodi/sql/coc-sql.org"
user-init-file
"~/org/emacs-cheatsheet.org"
user-init-file
;; "~/dev/tools/bash/Makefile"
"~/dev/brchess/src/board.c"
"~/org/emacs-cheatsheet.org")
;;"~/dev/g910/g910-gkey-macro-support/lib/data_mappers/char_uinput_mapper.py"
"~/dev/advent-of-code/2022/Makefile"
"~/dev/www/com.raoult/devs/php/chess/list-pgn-games.php")
;;"~/dev/advent-of-code/2022/Makefile"
;;"~/dev/www/com.raoult/devs/php/chess/list-pgn-games.php")
;; "~/dev/eudyptula/ID")
"personal files always loaded at startup (no visible window).")