From bac8a5d2822835cf47175d1162030653fadd5c09 Mon Sep 17 00:00:00 2001
From: johannst Default value:Parameter
#!/bin/zsh
function test() {
zparseopts -D -E -A opts f=flag o: -long:
- echo "flag $flag"
- echo "o $opts[-o]"
- echo "long $opts[--long]"
- echo "pos $1"
+ echo "flag $flag"
+ echo "o $opts[-o]"
+ echo "long $opts[--long]"
+ echo "pos $1"
}
test -f -o OPTION --long LONG_OPT POSITIONAL
@@ -387,9 +387,9 @@ The match results can be accessed via the
$MATCH
variable and
INPUT='title foo : 1234'
REGEX='^title (.+) : ([0-9]+)$'
if [[ $INPUT =~ $REGEX ]]; then
- echo "$MATCH" # title foo : 1234
- echo "$match[1]" # foo
- echo "$match[2]" # 1234
+ echo "$MATCH" # title foo : 1234
+ echo "$match[1]" # foo
+ echo "$match[2]" # 1234
fi
Completion
@@ -421,7 +421,7 @@ $words[CURRENT-1] # previous word (relative to cursor position)
MSG
simple string with header messageCOMP
array of completions where each entry is "opt:description"
COMP
array of completions where each entry is "opt:description"
function _foo() {
local -a opts
@@ -462,16 +462,16 @@ function _foo_color() {
colors+=('green:green color')
colors+=('red:red color')
colors+=('blue:blue color')
- _describe "color" colors
+ _describe "color" colors
}
function _foo() {
_arguments \
- "-c[define color]:color:->s_color" \
- "-s[select sound]:sound:(low high)" \
- "-f[select file]:file:_files" \
- "-d[select dir]:dir:_files -/" \
- "-h[help]"
+ "-c[define color]:color:->s_color" \
+ "-s[select sound]:sound:(low high)" \
+ "-f[select file]:file:_files" \
+ "-d[select dir]:dir:_files -/" \
+ "-h[help]"
case $state in
s_color) _foo_color;;
@@ -485,9 +485,9 @@ arguments such as
function _foo() {
_arguments \
- "1:opt 1:(a b c)" \
- ":opt next:(d e f)" \
- "*:opt all:(u v w)"
+ "1:opt 1:(a b c)" \
+ ":opt next:(d e f)" \
+ "*:opt all:(u v w)"
}
Explanation:
@@ -520,7 +520,7 @@ previous rules apply, so in our example forarg3, argN..
.
bar=${foo:-some_val} # if $foo set, then bar=$foo else bar=some_val
# alternate value
-bar=${foo:+bla $foo} # if $foo set, then bar="bla $foo" else bar=""
+bar=${foo:+bla $foo} # if $foo set, then bar="bla $foo" else bar=""
# check param set
bar=${foo:?msg} # if $foo set, then bar=$foo else exit and print msg
@@ -602,6 +602,19 @@ contains some nice visualization to explain bash redirections.
once.
vim -d <(grep foo bar) <(grep foo moose)
+Execute commands in a group with or without subshell. Can be used to easily +redirect stdout/stderr of all commands in the group into one file.
+# Group commands without subshell.
+v=abc ; { v=foo; echo $v; } ; echo $v
+# foo
+# foo
+
+# Group commands with subshell.
+v=abc ; ( v=foo; echo $v; ) ; echo $v
+# foo
+# abc
+
getopts
The getopts
builtin uses following global variables:
#!/bin/bash
function parse_args() {
- while getopts "f:c" PARAM; do
+ while getopts "f:c" PARAM; do
case $PARAM in
- f) echo "GOT -f $OPTARG";;
- c) echo "GOT -c";;
- *) echo "ERR: print usage"; exit 1;;
+ f) echo "GOT -f $OPTARG";;
+ c) echo "GOT -c";;
+ *) echo "ERR: print usage"; exit 1;;
esac
done
# users responsibility to reset OPTIND
@@ -648,14 +661,14 @@ The match results can be accessed via the $BASH_REMATCH
variable:
INPUT='title foo : 1234'
REGEX='^title (.+) : ([0-9]+)$'
if [[ $INPUT =~ $REGEX ]]; then
- echo "${BASH_REMATCH[0]}" # title foo : 1234
- echo "${BASH_REMATCH[1]}" # foo
- echo "${BASH_REMATCH[2]}" # 1234
+ echo "${BASH_REMATCH[0]}" # title foo : 1234
+ echo "${BASH_REMATCH[1]}" # foo
+ echo "${BASH_REMATCH[2]}" # 1234
fi
Caution: When specifying a regex
in the [[ ]]
block directly, quotes will be treated as part of the pattern.
-[[ $INPUT =~ "foo" ]]
will match against "foo"
not foo
!
+[[ $INPUT =~ "foo" ]]
will match against "foo"
not foo
!
Completion
The complete
builtin is used to interact with the completion system.
@@ -686,11 +699,11 @@ against words generated by option
.
# -u generate list with users
# -e generate list with exported variables
-# compare "f" against words "foo" "foobar" "bar" and generate matches
-compgen -W "foo foobar bar" "f"
+# compare "f" against words "foo" "foobar" "bar" and generate matches
+compgen -W "foo foobar bar" "f"
-# compare "hom" against file/dir names and generate matches
-compgen -d -f "hom"
+# compare "hom" against file/dir names and generate matches
+compgen -d -f "hom"
Skeleton to copy/paste for writing simple completions.
@@ -702,12 +715,12 @@ compgen -d -f "hom" local curr=$2 local prev=$3 - local opts="-c -s -f -h" + local opts="-c -s -f -h" case $prev in - -c) COMPREPLY=( $(compgen -W "green red blue" -- $curr) );; - -s) COMPREPLY=( $(compgen -W "low high" -- $curr) );; + -c) COMPREPLY=( $(compgen -W "green red blue" -- $curr) );; + -s) COMPREPLY=( $(compgen -W "low high" -- $curr) );; -f) COMPREPLY=( $(compgen -f -- $curr) );; - *) COMPREPLY=( $(compgen -W "$opts" -- $curr) );; + *) COMPREPLY=( $(compgen -W "$opts" -- $curr) );; esac } @@ -774,16 +787,16 @@ echo {a,b}{1,2} with:
when quoted or exported to the environment.
set -x BLA_PATH a:b:c:d
echo $BLA_PATH # a b c d
-echo "$BLA_PATH" # a:b:c:d (quoted)
+echo "$BLA_PATH" # a:b:c:d (quoted)
env | grep BLA_PATH # BLA_PATH=a:b:c:d (env)
set FOO_PATH x y z
echo $FOO_PATH # x y z
-echo "$FOO_PATH" # x:y:z
+echo "$FOO_PATH" # x:y:z
# sub-commands are not run in quotes
-echo "ls output: "(ls)
+echo "ls output: "(ls)
# 'noclobber', fail if 'log' already exists
@@ -852,7 +865,7 @@ funced foo # edit function 'foo'
Writing your own completions
complete
-function moose --d "my moose fn"
+function moose --d "my moose fn"
# h/help : short / long option (boolean)
# color : only long option (boolean)
# u/user= : option with required argument, only last specified is taken
@@ -862,18 +875,18 @@ funced foo # edit function 'foo'
or return
if set -ql _flag_help
- echo "usage ..."
+ echo "usage ..."
return 0
end
set -ql _flag_file
- and echo "file=$_flag_file | cnt:" (count $_flag_file)
+ and echo "file=$_flag_file | cnt:" (count $_flag_file)
set -ql _flag_color
- and echo "color=$_flag_color"
+ and echo "color=$_flag_color"
set -ql _flag_user
- and echo "user=$_flag_user"
+ and echo "user=$_flag_user"
end
# Delete all previous defined completions for 'moose'.
@@ -885,31 +898,31 @@ complete -c moose --no-files
# Help completion.
# -n specifies a conditions. The completion is only active if the command
# returns 0.
-complete -c moose -s h -l help -n "not __fish_contains_opt -s h help" \
- --description "Print usage help and exit"
+complete -c moose -s h -l help -n "not __fish_contains_opt -s h help" \
+ --description "Print usage help and exit"
# File completion.
# -F force complete files (overwrite --no-files).
# -r requires argument.
complete -c moose -s f -l file -F -r \
- --description "Specify file (can be passed multiple times)"
+ --description "Specify file (can be passed multiple times)"
# Color completion.
# -a options for completion.
# -x short for -r and --no-files (-f)
-complete -c moose -x -l color -a "red blue" \
- --description "Specify a color."
+complete -c moose -x -l color -a "red blue" \
+ --description "Specify a color."
# User completion.
# -a options for completion. Call a function to generate arguments.
-complete -c moose -x -s u -l user -a "(__fish_complete_users)" \
- --description "Specify a user"
+complete -c moose -x -s u -l user -a "(__fish_complete_users)" \
+ --description "Specify a user"
Prompt
The prompt is defined by the output of the fish_prompt
function.
function fish_prompt
set -l cmd_ret
- echo "> "(pwd) $cmd_ret" "
+ echo "> "(pwd) $cmd_ret" "
end
@@ -934,7 +947,7 @@ string split SEP STRING
# math
math -b hex 4096 # output dec as hex
math 0x1000 # output hex as dec
-math "log2(1024)" # call functions
+math "log2(1024)" # call functions
math -s0 7/3 # integer division (by default float)
# status
@@ -991,7 +1004,7 @@ tmux list-panes -F '#P' -t <s>:<w> list pane IDs for window <w&
tmux selectp -t <s>:<w>.<p> select pane <p> in window <w> in session <s>
# Run commands
-tmux send -t <s>:<w>.<p> "ls" C-m send cmds/keys to pane
+tmux send -t <s>:<w>.<p> "ls" C-m send cmds/keys to pane
tmux run -t <p> <sh-cmd> run shell command <sh-cmd> in background and report output on pane -t <p>
For example cycle through all panes in all windows in all sessions:
@@ -1120,7 +1133,7 @@ list-keys -t vi-copy list keymaps for vi-copy mode
branch has additional commits compared to remote branch).
git tag -a <tname> -m "descr" ........ creates an annotated tag (full object
+ git tag -a <tname> -m "descr" ........ creates an annotated tag (full object
containing tagger, date, ...)
git tag -l ........................... list available tags
git checkout tag/<tname> ............. checkout specific tag
@@ -1304,7 +1317,7 @@ multiple times. Actions with those patterns are executed exactly onceSpecial statements & functions
-
-
printf "fmt", args...
+printf "fmt", args...
Print format string, args are comma separated.
%s
string
@@ -1317,12 +1330,12 @@ For floats one can use %N.Mf
, N
is the total number in
M
.
-
-
sprintf("fmt", expr, ...)
+sprintf("fmt", expr, ...)
Format the expressions according to the format string. Similar as printf
,
but this is a function and return value can be assigned to a variable.
-
-
strftime("fmt")
+strftime("fmt")
Print time stamp formatted by fmt
.
%Y
full year (eg 2020)
@@ -1356,7 +1369,7 @@ prints the whole record.
Matches records not starting with #
.
Range patterns
-echo -e "a\nFOO\nb\nc\nBAR\nd" | \
+echo -e "a\nFOO\nb\nc\nBAR\nd" | \
awk '/FOO/,/BAR/ { print }'
/FOO/,/BAR/
define a range pattern of begin_pattern, end_pattern
. When
@@ -1364,13 +1377,17 @@ prints the whole record.
end_pattern
is matched the range is turned off. This matches every record
in the range inclusive.
An exclusive range must be handled explicitly, for example as follows.
-echo -e "a\nFOO\nb\nc\nBAR\nd" | \
- awk '/FOO/,/BAR/ { if (!($1 ~ "FOO") && !($1 ~ "BAR")) { print } }'
+echo -e "a\nFOO\nb\nc\nBAR\nd" | \
+ awk '/FOO/,/BAR/ { if (!($1 ~ "FOO") && !($1 ~ "BAR")) { print } }'
Access last fields in records
echo 'a b c d e f' | awk '{ print $NF $(NF-1) }'
Access last fields with arithmetic on the NF
number of fields variable.
+Split on multiple tokens
+echo 'a,b;c:d' | awk -F'[,;:]' '{ printf "1=%s | 4=%s\n", $1, $4 }'
+
+Use regex as field separator.
Capture in variables
# /proc/<pid>/status
# Name: cat
@@ -1382,7 +1399,7 @@ for f in /proc/*/status; do
cat $f | awk '
/^VmRSS/ { rss = $2/1024 }
/^Name/ { name = $2 }
- END { printf "%16s %6d MB\n", name, rss }';
+ END { printf "%16s %6d MB\n", name, rss }';
done | sort -k2 -n
We capture values from VmRSS
and Name
into variables and print them at the
@@ -1397,7 +1414,7 @@ a 1' | awk '{
}
END {
for (v in vals)
- printf "%s %d\n", v, vals[v] / cnts [v]
+ printf "%s %d\n", v, vals[v] / cnts [v]
}'
Capture keys and values from different columns and some up the values.
@@ -1405,7 +1422,7 @@ At the END
we compute the average of each key.
Run shell command and capture output
cat /proc/1/status | awk '
/^Pid/ {
- "ps --no-header -o user " $2 | getline user;
+ "ps --no-header -o user " $2 | getline user;
print user
}'
@@ -1914,7 +1931,7 @@ thread name <name>
Configuration
set disassembly-flavor <intel | att>
- Set the disassembly style "flavor".
+ Set the disassembly style "flavor".
set pagination <on | off>
Turn on/off gdb's pagination.
@@ -2187,7 +2204,7 @@ The wrapper will be executed before the debugee.
> rasm2 -a x86 'mov eax, 0xdeadbeef'
b8efbeadde
- > rasm2 -a x86 -d "b8efbeadde"
+ > rasm2 -a x86 -d "b8efbeadde"
mov eax, 0xdeadbeef
qemu(1)
@@ -2379,10 +2396,10 @@ qemu-system-x86_64 -monitor stdio -incoming tcp:0.0.0.0:12345
qemu-system-x86_64 -monitor stdio -cdrom <iso>
# Save VM state to file.
-(qemu) migrate "exec:gzip -c > vm.gz"
+(qemu) migrate "exec:gzip -c > vm.gz"
# Load VM from file.
-qemu-system-x86_64 -monitor stdio -incoming "exec: gzip -d -c vm.gz"
+qemu-system-x86_64 -monitor stdio -incoming "exec: gzip -d -c vm.gz"
The migration source machine and the migration target machine should be @@ -2394,7 +2411,7 @@ launched with the same parameters.
-cpu host \ -enable-kvm \ -kernel <dir>/arch/x86/boot/bzImage \ - -append "earlyprintk=ttyS0 console=ttyS0 nokaslr init=/init debug" \ + -append "earlyprintk=ttyS0 console=ttyS0 nokaslr init=/init debug" \ -initrd <dir>/initramfs.cpio.gz \ ... @@ -2410,7 +2427,7 @@ trace: test clean: $(RM) test test-bin test.o -.section .text, "ax" +
.section .text, "ax" .global _start _start: @@ -2474,7 +2491,7 @@ dependencies. package and sort by size.
pacman -Qetq | xargs pacman -Qi | awk '/Name/ { name=$3 } - /Installed Size/ { printf "%8.2f%s %s\n", $4, $5, name }' | + /Installed Size/ { printf "%8.2f%s %s\n", $4, $5, name }' | sort -h
Install package into different
root
directory but keep using the default @@ -2505,10 +2522,10 @@ digraph { // Add multiple edges at once. stage2 -> { stage3_1, stage3_2 } // Add edge with custom attributes. - stage3_2 -> stage4 [label="some text"] + stage3_2 -> stage4 [label="some text"] // Set custom attributes for specific node. - stage4 [color=green,fillcolor=lightgray,style="filled,dashed",label="s4"] + stage4 [color=green,fillcolor=lightgray,style="filled,dashed",label="s4"] // Create a subgraph. This can be used to group nodes/edges or as scope for // global node/edge attributes. @@ -2537,14 +2554,14 @@ digraph {Following snippet allows to select a window which is then captured.
@@ -2600,6 +2617,8 @@ c,21' | sort -k2 -n -t, -i edit file in place -i.bk edit file in place and create backup file (with .bk suffix, can be specified differently) + --follow-symlinks + follow symlinks when editing in place -e SCRIPT add SCRIPT to commands to be executed (can be specified multiple times) -f FILE add content of FILE to command to be executed @@ -2650,6 +2669,12 @@ echo -e 'aa\nbb' | sed '2aABC' echo -e 'aa\nbb' | sed '2cABC' # aa # ABC + +# Insert before pattern match. +echo -e 'aa\nbb' | sed '/bb/i 123' +# aa +# 123 +# bb#!/bin/bash -echo "Click on window to record .." +echo "Click on window to record .." # Extract window size and x,y offset. video_args=$(xwininfo \ | awk '/Absolute upper-left X:/ { xoff = $4 } /Absolute upper-left Y:/ { yoff=$4 } /Width:/ { if ($2 % 2 == 1) { width=$2-1; } else { width=$2; } } /Height:/ { if ($2 % 2 == 1) { height=$2-1; } else { height=$2; } } - END { printf "-video_size %dx%d -i :0.0+%d,%d", width, height, xoff, yoff }') + END { printf "-video_size %dx%d -i :0.0+%d,%d", width, height, xoff, yoff }') ffmpeg -framerate 25 -f x11grab $video_args -pix_fmt yuv420p $@ output.mp4
Substitute lines
+# Substitute by regex. @@ -2662,6 +2687,20 @@ echo -e 'aafooaa\ncc' | sed 's/foo/MOOSE/' # BAR # bar
Edit inplace through symlink
+touch file +ln -s file link +ls -l link +# lrwxrwxrwx 1 johannst johannst 4 Feb 7 23:02 link -> file + +sed -i --follow-symlinks '1iabc' link +ls -l link +# lrwxrwxrwx 1 johannst johannst 4 Feb 7 23:02 link -> file + +sed -i '1iabc' link +ls -l link +# -rw-r--r-- 1 johannst johannst 0 Feb 7 23:02 link +
gnuplot (1)
# Launch interactive shell. gnuplot @@ -2671,30 +2710,30 @@ gnuplot [opt] opt: -p ................ persist plot window -c <file> ......... run script file - -e "<cmd1>; .." ... run cmd(s) + -e "<cmd1>; .." ... run cmd(s)
Frequently used configuration
# Plot title. -set title "the plot" +set title "the plot" # Labels. -set xlabel "abc" -set ylabel "def" +set xlabel "abc" +set ylabel "def" # Output format, 'help set term' for all output formats. set term svg # Output file. -set output "out.svg" +set output "out.svg" # Make axis logarithmic to given base. set logscale x 2 # Change separator, default is whitespace. -set datafile separator "," +set datafile separator ","
Plot
# With specific style (eg lines, linespoint, boxes, steps, impulses, ..). -plot "<data_file>" with <plot_style> +plot "<data_file>" with <plot_style> > cat data.txt 1 1 3 @@ -2703,30 +2742,30 @@ plot "<data_file>" with <plot_style> 4 2 2 # Plot specific column. -plot "data.txt" using 1:2, "data.txt" using 1:3 -# Equivalent using the special file "", which re-uses the previous input file. -plot "data.txt" using 1:2, "" using 1:3 +plot "data.txt" using 1:2, "data.txt" using 1:3 +# Equivalent using the special file "", which re-uses the previous input file. +plot "data.txt" using 1:2, "" using 1:3 # Plot piped data. -plot "< head -n2 data.txt" +plot "< head -n2 data.txt" # Plot with alternate title. -plot "data.txt" title "moose" +plot "data.txt" title "moose"
Example: multiple data sets in on plot
# file: mem_lat.plot -set title "memory latency (different strides)" -set xlabel "array in KB" -set ylabel "cycles / access" +set title "memory latency (different strides)" +set xlabel "array in KB" +set ylabel "cycles / access" set logscale x 2 -plot "stride_32.txt" title "32" with linespoints, \ - "stride_64.txt" title "64" with linespoints, \ - "stride_128.txt" title "128" with linespoints, \ - "stride_256.txt" title "256" with linespoints, \ - "stride_512.txt" title "512" with linespoints +plot "stride_32.txt" title "32" with linespoints, \ + "stride_64.txt" title "64" with linespoints, \ + "stride_128.txt" title "128" with linespoints, \ + "stride_256.txt" title "256" with linespoints, \ + "stride_512.txt" title "512" with linespoints
On Linux x86_64,
@@ -3077,7 +3116,7 @@ databases for the different intel uarchs. corresponding uarch, just grab the family model from the procfs.mem_lat.c
provides an example which can be run as follows.cat /proc/cpuinfo | awk '/^vendor_id/ { V=$3 } /^cpu family/ { F=$4 } - /^model\s*:/ { printf "%s-%d-%x\n",V,F,$3 }' + /^model\s*:/ { printf "%s-%d-%x\n",V,F,$3 }'
The table in performance monitoring events describes how @@ -3111,7 +3150,7 @@ perf script --per-event-dump
Examples
Estimate max instructions per cycle
-#define NOP4 "nop\nnop\nnop\nnop\n" +
-#define NOP4 "nop\nnop\nnop\nnop\n" #define NOP32 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 NOP4 #define NOP256 NOP32 NOP32 NOP32 NOP32 NOP32 NOP32 NOP32 NOP32 #define NOP2048 NOP256 NOP256 NOP256 NOP256 NOP256 NOP256 NOP256 NOP256 @@ -3370,7 +3409,7 @@ disassemble with
objdump
.To re-create that case, we just assemble and link some ELF file and then create a raw binary of the text section with
objcopy
.# file: test.s -.section .text, "ax" +.section .text, "ax" .global _start _start: @@ -3582,7 +3621,7 @@ int* P = reinterpret_cast<int*>(C); // Cast is ok, not yet UB.
On
-gcc
strict aliasing is enabled starting with-O2
.for i in {0..3} g s; do echo "-O$i $(g++ -Q --help=optimizers -O$i | grep fstrict-aliasing)"; done +
for i in {0..3} g s; do echo "-O$i $(g++ -Q --help=optimizers -O$i | grep fstrict-aliasing)"; done -O0 -fstrict-aliasing [disabled] -O1 -fstrict-aliasing [disabled] -O2 -fstrict-aliasing [enabled] @@ -3635,13 +3674,13 @@ to violate self defined contract, see // Base case with one parameter. template<int P> void show_int() { - printf("%d\n", P); + printf("%d\n", P); } // General case with at least two parameters, to disambiguate from base case. template<int P0, int P1, int... Params> void show_int() { - printf("%d, ", P0); + printf("%d, ", P0); show_int<P1, Params...>(); } @@ -3656,13 +3695,13 @@ void show(const T& t) { // General case with at least two parameters, to disambiguate from base case. template<typename T0, typename T1, typename... Types> void show(const T0& t0, const T1& t1, const Types&... types) { - std::cout << t0 << ", "; + std::cout << t0 << ", "; show(t1, types...); } int main() { show_int<1, 2, 3, 4, 5>(); - show(1, 1.0, "foo", 'a'); + show(1, 1.0, "foo", 'a'); }
Forwarding reference (fwd ref)
@@ -3712,21 +3751,21 @@ void fwd_wrapper(T&& param) { // forwarding reference int main() { { - std::puts("==> wrapper rvalue reference"); + std::puts("==> wrapper rvalue reference"); wrapper(M{}); // calls use(M&). - std::puts("==> wrapper lvalue reference"); + std::puts("==> wrapper lvalue reference"); struct M m; wrapper(m); // calls use(M&). } { - std::puts("==> fwd_wrapper rvalue reference"); + std::puts("==> fwd_wrapper rvalue reference"); fwd_wrapper(M{}); // calls use(M&&). - std::puts("==> fwd_wrapper lvalue reference"); + std::puts("==> fwd_wrapper lvalue reference"); struct M m; fwd_wrapper(m); // calls use(M&). @@ -3752,8 +3791,8 @@ struct any_of<T, U0, U...> : any_of<T, U...> {}; template<typename T, typename... U> constexpr bool any_of_v = any_of<T, U...>::value; -static_assert(any_of_v<int, char, bool, int>, ""); -static_assert(!any_of_v<int, char, bool, float>, ""); +static_assert(any_of_v<int, char, bool, int>, ""); +static_assert(!any_of_v<int, char, bool, float>, "");Example: SFINAE (enable_if)
Provide a single entry point
Invoke
to call someOperations
. @@ -3799,16 +3838,16 @@ namespace impl { template<typename Ctx, template<typename> class Op, typename... P, enable_if_bool<has_dst<Op<Ctx>>> = true> void Invoke(const Ctx& C, P... params) { - std::cout << "Invoke " << Op<Ctx>::Name << '\n'; + std::cout << "Invoke " << Op<Ctx>::Name << '\n'; typename Op<Ctx>::Return R = impl::Invoke<Ctx, Op>(C, params...); - std::cout << "returned -> " << R << '\n'; + std::cout << "returned -> " << R << '\n'; } // Invoke an OPERATION which has *NOT* a DESTINATION with arbitrary number of arguments. template<typename Ctx, template<typename> class Op, typename... P, disable_if_bool<has_dst<Op<Ctx>>> = true> void Invoke(const Ctx& C, P... params) { - std::cout << "Invoke " << Op<Ctx>::Name << " without destination." << '\n'; + std::cout << "Invoke " << Op<Ctx>::Name << " without destination." << '\n'; impl::Invoke<Ctx, Op>(C, params...); } @@ -3816,7 +3855,7 @@ void Invoke(const Ctx& C, P... params) { struct Ctx { void out(const char* s, unsigned v) const { - printf("%s%x\n", s, v); + printf("%s%x\n", s, v); } }; @@ -3826,7 +3865,7 @@ template<typename Ctx> struct OpA { using HasCtx = std::false_type; using Return = int; - static constexpr const char* const Name = "OpA"; + static constexpr const char* const Name = "OpA"; constexpr Return operator()(int a, int b) const { return a + b; @@ -3837,10 +3876,10 @@ template<typename Ctx> struct OpB { using HasCtx = std::true_type; using Return = void; - static constexpr const char* const Name = "OpB"; + static constexpr const char* const Name = "OpB"; Return operator()(const Ctx& C, unsigned a) const { - C.out("a = ", a); + C.out("a = ", a); } }; @@ -3906,7 +3945,7 @@ struct registry { const auto it = m_fns.find(nm); if (it == m_fns.end()) { static_assert(std::is_default_constructible_v<RET>, - "RET must be default constructible"); + "RET must be default constructible"); return {}; } return std::invoke(it->second, p...); @@ -3917,7 +3956,7 @@ struct registry { static bool regfn_##REGISTRY##NAME() { \ const bool r = REGISTRY::get().add(#NAME, NAME); \ if (!r) { \ - std::puts("Failed to register test " #NAME ", same name already registered!"); \ + std::puts("Failed to register test " #NAME ", same name already registered!"); \ std::abort(); \ } \ return r; \ @@ -3933,10 +3972,10 @@ struct registry { using REG1 = registry<void>; TEST(REG1, test1) { - std::puts("REG1::test1"); + std::puts("REG1::test1"); } TEST(REG1, test2) { - std::puts("REG1::test2"); + std::puts("REG1::test2"); } // -- Usage 2 with convenience macro wrapper. @@ -3945,18 +3984,18 @@ using REG2 = registry<void, bool>; #define TEST2(NAME, ...) TEST(REG2, NAME, ##__VA_ARGS__) TEST2(test1, bool val) { - printf("REG2::test1 val %d\n", val); + printf("REG2::test1 val %d\n", val); } int main() { const auto& R1 = REG1::get(); R1.dump(); - R1.invoke("test1"); - R1.invoke("test2"); + R1.invoke("test1"); + R1.invoke("test2"); const auto& R2 = REG2::get(); R2.dump(); - R2.invoke("test1", true); + R2.invoke("test1", true); return 0; } @@ -4013,7 +4052,7 @@ struct Entry { }; int main() { - static_assert(is_entry_v<Entry<bool>>, ""); + static_assert(is_entry_v<Entry<bool>>, ""); }The main mechanic can be explained with the following reduced example. If one @@ -4037,7 +4076,7 @@ struct A { struct B {}; -static_assert(is_valid<A>::value, "is true"); +static_assert(is_valid<A>::value, "is true"); // * Compare template arg list with primary template, we only supplied one // arg, the second one will be defaulted as // is_valid<A, void> @@ -4051,7 +4090,7 @@ static_assert(is_valid<A>::value, "is true"); // * Specialization (2) matches <A, void> // * Pick the most specialized version -> (2) -static_assert(!is_valid<B>::value, "is false"); +static_assert(!is_valid<B>::value, "is false"); // * Compare template arg list with primary template, we only supplied one // arg, the second one will be defaulted as // is_valid<A, void> @@ -4102,7 +4141,7 @@ struct pair<int, int> { }; int main() { - static_assert(pair<int>::kind == kIntBool, ""); + static_assert(pair<int>::kind == kIntBool, ""); // * Compare template arg list with primary template, we only supplied one // arg, the second one will be defaulted as // pair<int, bool> @@ -4114,7 +4153,7 @@ int main() { // * (4) <int, bool> pattern does not match // * Pick the most specialized version -> (3) - static_assert(pair<char, char>::kind == kTT, ""); + static_assert(pair<char, char>::kind == kTT, ""); // * Compare template arg list against available specializations, this will // try to match the pattern <char, char> against the patterns defined in the // partial specializations. @@ -4123,7 +4162,7 @@ int main() { // * (4) <char, char> pattern does not match // * Pick the most specialized version -> (2) - static_assert(pair<int, int>::kind == kIntInt, ""); + static_assert(pair<int, int>::kind == kIntInt, ""); // * Compare template arg list against available specializations, this will // try to match the pattern <int, int> against the patterns defined in the // partial specializations. @@ -4132,7 +4171,7 @@ int main() { // * (4) <int, int> pattern does not match // * Pick the most specialized version -> (3) - static_assert(pair<char, short>::kind == kPrimary, ""); + static_assert(pair<char, short>::kind == kPrimary, ""); // * Compare template arg list against available specializations, this will // try to match the pattern <char, short> against the patterns defined in the // partial specializations. @@ -4153,25 +4192,25 @@ struct S {}; struct M { M() { - std::puts("M()"); + std::puts("M()"); } M(const M&) { - std::puts("M(M&)"); + std::puts("M(M&)"); } M(M&&) { - std::puts("M(M&&)"); + std::puts("M(M&&)"); } M& operator=(const M&) = delete; M& operator=(M&&) = delete; M(S&, int) { - std::puts("M(S&)"); + std::puts("M(S&)"); } M(S&&, int) { - std::puts("M(S&&)"); + std::puts("M(S&&)"); } ~M() { - std::puts("~M()"); + std::puts("~M()"); } }; @@ -4219,11 +4258,11 @@ struct option { }; int main() { - std::puts("==> case 1"); + std::puts("==> case 1"); // invokes M(S&&, int) option<M> opt1(S{}, 123); - std::puts("==> case 2"); + std::puts("==> case 2"); // invokes M() + M(M&&) option<M> x /* option(M&&) + M(M&&) */ = M{} /* M() */; } @@ -4295,7 +4334,7 @@ accordingly to reduce number of jump instructions. See on compiler explorer.
The semantics of this hint are as follows, the compiler prioritises
-expr == cond
. So__builtin_expect(expr, 0)
means that we expect theexpr
to be0
most of the time.echo " +
echo " extern void foo(); extern void bar(); void run0(int x) { @@ -4306,7 +4345,7 @@ void run1(int x) { if (__builtin_expect(x,1)) { foo(); } else { bar(); } } -" | gcc -O2 -S -masm=intel -o /dev/stdout -xc - +" | gcc -O2 -S -masm=intel -o /dev/stdout -xc -
Will generate something similar to the following.
@@ -4332,7 +4371,7 @@ run1:
ABI (Linux)
-
- C ABI - SystemV ABI
+- C ABI (x86_64) - SystemV ABI
- C++ ABI - C++ Itanium ABI
cmake(1)
@@ -4362,7 +4401,7 @@ target_compile_definitions(liba INTERFACE DEF_INTERFACE) add_executable(main main.cc) target_link_libraries(main liba)> touch liba.cc; echo "int main() {}" > main.cc +
> touch liba.cc; echo "int main() {}" > main.cc > cmake -B build -S . -G Ninja > ninja -C build -j1 --verbose [1/4] /usr/bin/c++ -DDEF_PRIVATE -DDEF_PUBLIC [..] .../liba.cc @@ -4409,12 +4448,12 @@ the recipe, make provides a set of automatic variables to work with: all: foobar blabla foo% bla%: aaa bbb bbb - @echo "@ = $@" - @echo "< = $<" - @echo "^ = $^" - @echo "+ = $+" - @echo "* = $*" - @echo "----" + @echo "@ = $@" + @echo "< = $<" + @echo "^ = $^" + @echo "+ = $+" + @echo "* = $*" + @echo "----" aaa: bbb: @@ -4503,10 +4542,10 @@ Therefore the following is a code smell:
// at startup LD_LIBRARY_PATH=/moose // Assume /foo/libbar.so -setenv("LD_LIBRARY_PATH", "/foo", true /* overwrite */); +setenv("LD_LIBRARY_PATH", "/foo", true /* overwrite */); // Will look in /moose and NOT in /foo. -dlopen("libbar.so", RTLD_LAZY); +dlopen("libbar.so", RTLD_LAZY);
LD_PRELOAD: Initialization Order and Link Map
Libraries specified in
-LD_PRELOAD
are loaded fromleft-to-right
but @@ -4630,10 +4669,10 @@ Symbol table '.dynsym' contains 342 entries: static linking against the library. The following dump shows that thetmp
program linked againstlpthread
will depend on the symbol versionGLIBC_2.3.2
, which is the default version.@@ -4772,7 +4811,7 @@ Symbol table '.dynsym' contains 14 entries: #include <assert.h> // Links against default symbol in the lib.so. -extern "C" void func(); +extern "C" void func(); int main() { // Call the default version. @@ -4782,10 +4821,10 @@ int main() { typedef void (*fnptr)(); // Unversioned lookup. - fnptr fn_v0 = (fnptr)dlsym(RTLD_DEFAULT, "func"); + fnptr fn_v0 = (fnptr)dlsym(RTLD_DEFAULT, "func"); // Version lookup. - fnptr fn_v1 = (fnptr)dlvsym(RTLD_DEFAULT, "func", "LIB_V1"); - fnptr fn_v2 = (fnptr)dlvsym(RTLD_DEFAULT, "func", "LIB_V2"); + fnptr fn_v1 = (fnptr)dlvsym(RTLD_DEFAULT, "func", "LIB_V1"); + fnptr fn_v2 = (fnptr)dlvsym(RTLD_DEFAULT, "func", "LIB_V2"); assert(fn_v0 != 0); assert(fn_v1 != 0); @@ -4821,26 +4860,26 @@ func_v2 def log(f: Callable[[int], None]) -> Callable[[int], None]: def inner(x: int): - print(f"log::inner f={f.__name__} x={x}") + print(f"log::inner f={f.__name__} x={x}") f(x) return inner @log def some_fn(x: int): - print(f"some_fn x={x}") + print(f"some_fn x={x}") def log_tag(tag: str) -> Callable[[Callable[[int], None]], Callable[[int], None]]: def decorator(f: Callable[[int], None]) -> Callable[[int], None]: def inner(x: int): - print(f"log_tag::inner f={f.__name__} tag={tag} x={x}") + print(f"log_tag::inner f={f.__name__} tag={tag} x={x}") f(x) return inner return decorator -@log_tag("some_tag") +@log_tag("some_tag") def some_fn2(x: int): - print(f"some_fn2 x={x}") + print(f"some_fn2 x={x}")> echo "#include <pthread.h> +
> echo "#include <pthread.h> int main() { return pthread_cond_wait(0,0); - }" | gcc -o tmp -xc - -lpthread; + }" | gcc -o tmp -xc - -lpthread; readelf -W --dyn-syms tmp | grep pthread_cond_wait; Symbol table '.dynsym' contains 7 entries: @@ -4705,23 +4744,23 @@ symbol multiple times but in different versions. // ..@ -> Is the unversioned symbol. // ..@@.. -> Is the default symbol. -__asm__(".symver func_v0,func@"); -__asm__(".symver func_v1,func@LIB_V1"); -__asm__(".symver func_v2,func@@LIB_V2"); +__asm__(".symver func_v0,func@"); +__asm__(".symver func_v1,func@LIB_V1"); +__asm__(".symver func_v2,func@@LIB_V2"); -extern "C" { - void func_v0() { puts("func_v0"); } - void func_v1() { puts("func_v1"); } - void func_v2() { puts("func_v2"); } +extern "C" { + void func_v0() { puts("func_v0"); } + void func_v1() { puts("func_v1"); } + void func_v2() { puts("func_v2"); } } -__asm__(".symver _Z11func_cpp_v1i,_Z8func_cppi@LIB_V1"); -__asm__(".symver _Z11func_cpp_v2i,_Z8func_cppi@@LIB_V2"); +__asm__(".symver _Z11func_cpp_v1i,_Z8func_cppi@LIB_V1"); +__asm__(".symver _Z11func_cpp_v2i,_Z8func_cppi@@LIB_V2"); -void func_cpp_v1(int) { puts("func_cpp_v1"); } -void func_cpp_v2(int) { puts("func_cpp_v2"); } +void func_cpp_v1(int) { puts("func_cpp_v1"); } +void func_cpp_v2(int) { puts("func_cpp_v2"); } -void func_cpp(int) { puts("func_cpp_v2"); } +void func_cpp(int) { puts("func_cpp_v2"); }
Version script for
@@ -4729,8 +4768,8 @@ exported from the ELF file. LIB_V1 { global: func; - extern "C++" { - "func_cpp(int)"; + extern "C++" { + "func_cpp(int)"; }; local: *; @@ -4739,8 +4778,8 @@ LIB_V1 { LIB_V2 { global: func; - extern "C++" { - "func_cpp(int)"; + extern "C++" { + "func_cpp(int)"; }; } LIB_V1;libfoo
which defines which symbols for which versions are exported from the ELF file.Walrus operator [run]
Walrus operator
@@ -4852,20 +4891,20 @@ def foo(ret: Optional[int]) -> Optional[int]: return ret if r := foo(None): - print(f"foo(None) -> {r}") + print(f"foo(None) -> {r}") if r := foo(1337): - print(f"foo(1337) -> {r}") + print(f"foo(1337) -> {r}") # Example 2: while let statements toks = iter(['a', 'b', 'c']) while tok := next(toks, None): - print(f"{tok}") + print(f"{tok}") # Example 3: list comprehension -print([tok for t in [" a", " ", " b "] if (tok := t.strip())]) +print([tok for t in [" a", " ", " b "] if (tok := t.strip())]):=
added since python 3.8.Unittest [run]
Run unittests directly from the command line as
@@ -4893,19 +4932,19 @@ class MyTest(unittest.TestCase):# file: test.py def sum(a: int, b: int) -> int: - """Sum a and b. + """Sum a and b. >>> sum(1, 2) 3 >>> sum(10, 20) 30 - """ + """ return a + b
timeit
Micro benchmarking.
-@@ -5393,7 +5432,7 @@ mkswap /swapfile swapon /swapfile # Persistent setup of swap file. -echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab +echo "/swapfile none swap sw 0 0" | sudo tee -a /etc/fstab # Disable swap file (until next reboot). swapoff /swapfile @@ -5456,7 +5495,7 @@ filepython -m timeit '[x.strip() for x in ["a ", " b"]]' +
python -m timeit '[x.strip() for x in ["a ", " b"]]'
gcov(1)
Generate code coverage reports in text format.
@@ -4934,9 +4973,9 @@ generated for a single file for example such as void tell_me(int desc) { if (desc & 1) { - std::puts("this"); + std::puts("this"); } else { - std::puts("that"); + std::puts("that"); } } @@ -4982,9 +5021,9 @@ clean: -: 4: 2: 5:void tell_me(int desc) { 2: 6: if (desc & 1) { - 2: 7: std::puts("this"); + 2: 7: std::puts("this"); -: 8: } else { - #####: 9: std::puts("that"); + #####: 9: std::puts("that"); -: 10: } 2: 11:} -: 12: @@ -5007,8 +5046,8 @@ workload. #define NOINLINE __attribute__((noinline)) -NOINLINE void foo() { puts("foo()"); } -NOINLINE void bar() { puts("bar()"); } +NOINLINE void foo() { puts("foo()"); } +NOINLINE void bar() { puts("bar()"); } int main(int argc, char *argv[]) { if (argc == 2) { @@ -5049,7 +5088,7 @@ clang -o test test.cc -O3 -fprofile-instr-generate # Collect profiling data from multiple runs. for i in {0..10}; do - LLVM_PROFILE_FILE="prof.clang/%p.profraw" ./test $(seq 0 $i) + LLVM_PROFILE_FILE="prof.clang/%p.profraw" ./test $(seq 0 $i) done # Merge raw profiling data into single profile data. @@ -5186,7 +5225,7 @@ Description=Test logger [Service] Type=oneshot -ExecStart=logger "Hello from test unit"' > ~/.config/systemd/user/test.service +ExecStart=logger "Hello from test unit"' > ~/.config/systemd/user/test.service # Run unit systemctl --user start test @@ -5238,7 +5277,7 @@ In a typical bash/zsh this can be done as /proc/sys/kernel/core_uses_pid - 1 => Append ".<pid>" suffic to the coredump file name + 1 => Append ".<pid>" suffic to the coredump file name (pid of the dumping process). 0 => Do not append the suffix./proc/bus/input/devices
in the proc filesystem can be consulteThis yields entries as follows and shows which
Handlers
are assigned to whichName
.I: Bus=0018 Vendor=04f3 Product=0033 Version=0000 -N: Name="Elan Touchpad" +N: Name="Elan Touchpad" ... H: Handlers=event15 mouse0 ... @@ -5481,9 +5520,9 @@ struct input_event { const char* type(unsigned short t) { static char buf[32]; - const char* fmt = "0x%x"; + const char* fmt = "0x%x"; switch (t) { -#define FMT(TYPE) case TYPE: fmt = #TYPE"(0x%x)"; break +#define FMT(TYPE) case TYPE: fmt = #TYPE"(0x%x)"; break FMT(EV_SYN); FMT(EV_KEY); FMT(EV_REL); @@ -5496,9 +5535,9 @@ const char* type(unsigned short t) { const char* code(unsigned short c) { static char buf[32]; - const char* fmt = "0x%x"; + const char* fmt = "0x%x"; switch (c) { -#define FMT(CODE) case CODE: fmt = #CODE"(0x%x)"; break +#define FMT(CODE) case CODE: fmt = #CODE"(0x%x)"; break FMT(BTN_LEFT); FMT(BTN_RIGHT); FMT(BTN_MIDDLE); @@ -5514,7 +5553,7 @@ const char* timefmt(const struct timeval* t) { assert(t); struct tm* lt = localtime(&t->tv_sec); // Returns pointer to static tm object. static char buf[64]; - strftime(buf, sizeof(buf), "%H:%M:%S", lt); + strftime(buf, sizeof(buf), "%H:%M:%S", lt); return buf; } @@ -5528,7 +5567,7 @@ int main(int argc, char* argv[]) { while (1) { int ret = read(fd, &inp, sizeof(inp)); assert(ret == sizeof(inp)); - printf("time: %s type: %s code: %s value: 0x%x\n", + printf("time: %s type: %s code: %s value: 0x%x\n", timefmt(&inp.time), type(inp.type), code(inp.code), inp.value); } } @@ -5559,17 +5598,17 @@ drwxrwxr-x+ 2 root root 4 11. Jun 14:26 foo/ getfacl /tank/foo
Modify acl entries
-# Add acl entry for user "user123". -setfacl -m "u:user123:rwx" /tank/foo +
# Add acl entry for user "user123". +setfacl -m "u:user123:rwx" /tank/foo -# Remove entry for user "user123". -setfacl -x "u:user123" /tank/foo +# Remove entry for user "user123". +setfacl -x "u:user123" /tank/foo -# Add acl entry for group "group456". -setfacl -m "g:group456:rx" /tank/foo +# Add acl entry for group "group456". +setfacl -m "g:group456:rx" /tank/foo # Add acl entry for others. -setfacl -m "o:rx" /tank/foo +setfacl -m "o:rx" /tank/foo # Remove extended acl entries. setfacl -b /tank/foo @@ -5578,7 +5617,7 @@ setfacl -b /tank/foo
The
mask
defines the maximum access rights that can be given to users and groups.# Update the mask. -setfacl -m "m:rx" /tank/foo +setfacl -m "m:rx" /tank/foo # List acl entries. getfacl /tank/foo @@ -5867,7 +5906,7 @@ tcp.dstport == 80 Filter for tcp destinatio port. tcp/udp/ssh/wg/... Filter for protocol. -"and/or/not/!" and "()" can be used to build filter expressions. +"and/or/not/!" and "()" can be used to build filter expressions.
Use
@@ -5904,7 +5943,7 @@ firewall-cmd --add-service <SERVICE> # Add a specific port. firewall-cmd --add-port 8000/tcp # Add a rich rule (eg port forwarding, dnat). -firewall-cmd --add-rich-rule 'rule family="ipv4" forward-port port="80" protocol="tcp" to-port="8080"' +firewall-cmd --add-rich-rule 'rule family="ipv4" forward-port port="80" protocol="tcp" to-port="8080"'tshak -G
to list all fields that can be used in display filters.Remove entries
# Remove service. @@ -5912,7 +5951,7 @@ firewall-cmd --remove-service <SERVICE> # Remove port. firewall-cmd --remove-port 8000/tcp # Remove rich rule. -firewall-cmd --remove-rich-rule 'rule family="ipv4" forward-port port="80" protocol="tcp" to-port="8080"' +firewall-cmd --remove-rich-rule 'rule family="ipv4" forward-port port="80" protocol="tcp" to-port="8080"'
References
@@ -6047,11 +6086,11 @@ nc localhost 8200 padding-left: 1em; } </style> -<div class="grid-2col"> - <div class="col1"> +<div class="grid-2col"> + <div class="col1"> <p>Some text in the first column.</p> </div> - <div class="col2"> + <div class="col2"> <p>Some text in the second column.</p> </div> </div> @@ -6063,9 +6102,9 @@ nc localhost 8200 display: grid; grid-template-columns: 1fr 2fr; grid-template-areas: - "h h" - "s m" - "f f"; + "h h" + "s m" + "f f"; gap: 1em; } .gh { @@ -6094,21 +6133,21 @@ p { margin: 1em; } </style> -<div class="page-grid"> - <div class="gh"> - <ul class="nav-items"> - <li class="nav-item"><a href="">aa</a></li> - <li class="nav-item"><a href="">bb</a></li> - <li class="nav-item"><a href="">cc</a></li> +<div class="page-grid"> + <div class="gh"> + <ul class="nav-items"> + <li class="nav-item"><a href="">aa</a></li> + <li class="nav-item"><a href="">bb</a></li> + <li class="nav-item"><a href="">cc</a></li> </ul> </div> - <div class="gs"> + <div class="gs"> <p>Some text in the second column.</p> </div> - <div class="gm"> + <div class="gm"> <p>Some text in the second column.</p> </div> - <div class="gf"> + <div class="gf"> <p>Some text in the second column.</p> </div> </div> @@ -6118,58 +6157,58 @@ p {
<script> const showTab = (E, T) => { - const TABS = Array.from(document.getElementsByClassName("content")); + const TABS = Array.from(document.getElementsByClassName("content")); TABS.forEach(T => { - T.style.display = "none"; + T.style.display = "none"; }); - document.getElementById(T).style.display = "block"; + document.getElementById(T).style.display = "block"; }; window.onload = () => { - document.getElementById("bTab1").onclick = (E) => { - showTab(E, "tTab1"); + document.getElementById("bTab1").onclick = (E) => { + showTab(E, "tTab1"); }; - document.getElementById("bTab2").onclick = (E) => { - showTab(E, "tTab2"); + document.getElementById("bTab2").onclick = (E) => { + showTab(E, "tTab2"); }; } </script> -<button type="button" id="bTab1">Tab1</button> -<button type="button" id="bTab2">Tab2</button> +<button type="button" id="bTab1">Tab1</button> +<button type="button" id="bTab2">Tab2</button> -<div id="tTab1" class="content" style="display: block;"> +<div id="tTab1" class="content" style="display: block;"> <p>Some content goes here ...</p> </div> -<div id="tTab2" class="content" style="display: none;"> +<div id="tTab2" class="content" style="display: none;"> <p>... and there.</p> </div>
css
selector
-
.moose
element with class<div class = "moose"></div> // selected -<div class = "bar"></div> // NOT selected +
<div class = "moose"></div> // selected +<div class = "bar"></div> // NOT selected
-
.moose.bar
element with multiple classes<div class = "moose bar"></div> // selected -<div class = "bar"></div> // NOT selected +
<div class = "moose bar"></div> // selected +<div class = "bar"></div> // NOT selected
-
.moose .bar
descendant element with classes-- cgit v1.2.3<div class = "moose"> - <div class = "bar"></div> // selected +
<div class = "moose"> + <div class = "bar"></div> // selected </div> -<div class = "bar"></div> // NOT selected +<div class = "bar"></div> // NOT selected
p
specific element<p></p> // selected <div></div> // NOT selected
-
p.bar
specific element with class@@ -7135,7 +7174,7 @@ x28-x31 t3-t6 temp regs #include <asm/unistd.h> // syscall NRs - .section .text, "ax", @progbits + .section .text, "ax", @progbits .balign 4 // align code on 4byte boundary .global _start _start: @@ -7150,9 +7189,9 @@ _start: ecall .balign 8 // align data on 8byte boundary - .section .rodata, "a", @progbits + .section .rodata, "a", @progbits greeting: - .asciz "Hi ASM-World!\n" + .asciz "Hi ASM-World!\n" greeting_len: .int .-greeting<p class = "bar"></p> // selected -<p class = "foo"></p> // NOT selected +
<p class = "bar"></p> // selected +<p class = "foo"></p> // NOT selected
p,div
any element@@ -7041,7 +7080,7 @@ mov fp, sp // FP points to frame record .arch armv7-a - .section .text, "ax" + .section .text, "ax" .balign 4 // Emit `arm` instructions, same as `.arm` directive. @@ -7070,9 +7109,9 @@ _do_greet: bx lr .balign 8 // align data on 8byte boundary - .section .rodata, "a" + .section .rodata, "a" greeting: - .asciz "Hi ASM-World!\n" + .asciz "Hi ASM-World!\n" greeting_len: .int .-greeting<p></p> // selected @@ -6187,7 +6226,7 @@ window.onload = () => {
Chart.js
Minimal example with external tooltips
-<canvas id="myChart" style="margin:5em;"></canvas> +
@@ -6617,7 +6656,7 @@ Hi ASM-World!<canvas id="myChart" style="margin:5em;"></canvas> <script> const get_or_create_tooltip = (id) => { @@ -6223,12 +6262,12 @@ const render_tooltip = (context) => { // -- Format new tooltip. const link = document.createElement('a'); - link.href = "https://github.com/johannst"; - link.innerHTML = "X:" + x + " Y:" + y; + link.href = "https://github.com/johannst"; + link.innerHTML = "X:" + x + " Y:" + y; // -- Remove previous child element and add new one. const table = tooltip_elem.querySelector('table'); - table.innerHTML = ""; + table.innerHTML = ""; table.appendChild(link); // -- Get absolute X/Y position of the top left corner of the canvas. @@ -6240,9 +6279,9 @@ const render_tooltip = (context) => { tooltip_elem.style.font = tooltip.options.bodyFont.string; // -- Place the tooltip (I) left or (II) right of the data point. - if (tooltip.xAlign === "right") { + if (tooltip.xAlign === "right") { tooltip_elem.style.transform = 'translate(-100%, 0)'; // (I) - } else if (tooltip.xAlign === "left") { + } else if (tooltip.xAlign === "left") { tooltip_elem.style.transform = 'translate(0%, 0)'; // (II) } } @@ -6368,7 +6407,7 @@ mov rax, qword ptr [rbx+4*rcx] // load val at [rbx+4*rcx] into rax
lea rax, [rip+.my_str] // load addr of .my_str into rax ... .my_str: -.asciz "Foo" +.asciz "Foo"
Load effective address:
-mov rax, 2 @@ -6418,7 +6457,7 @@ mov al, 0xaa mov cx, 0x10 rep stosb
SysV x86_64 ABI
+SysV x86_64 ABI
Passing arguments to functions
- Integer/Pointer arguments @@ -6589,7 +6628,7 @@ must must save these registers in case they are used. .intel_syntax noprefix - .section .text, "ax", @progbits + .section .text, "ax", @progbits .global _start _start: mov rdi, 1 # fd @@ -6602,9 +6641,9 @@ _start: mov rax, 60 # exit(2) syscall nr syscall - .section .rdonly, "a", @progbits + .section .rdonly, "a", @progbits greeting: - .asciz "Hi ASM-World!\n" + .asciz "Hi ASM-World!\n" greeting_len: .int .-greeting
References
-
- SystemV AMD64 ABI
+- SystemV AMD64 ABI
- AMD64 Vol1: Application Programming
- AMD64 Vol2: System Programming
- AMD64 Vol3: General-Purpose & System Instructions
@@ -6809,7 +6848,7 @@ ret .arch armv8-a - .section .text, "ax", @progbits + .section .text, "ax", @progbits .balign 4 // align code on 4byte boundary .global _start _start: @@ -6825,9 +6864,9 @@ _start: svc 0 .balign 8 // align data on 8byte boundary - .section .rodata, "a", @progbits + .section .rodata, "a", @progbits greeting: - .asciz "Hi ASM-World!\n" + .asciz "Hi ASM-World!\n" greeting_len: .int .-greeting