From bac8a5d2822835cf47175d1162030653fadd5c09 Mon Sep 17 00:00:00 2001 From: johannst Date: Thu, 15 Feb 2024 23:29:57 +0000 Subject: deploy: 4485708c972815bbb6df7f5a228683aa855d553d --- print.html | 577 +++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 308 insertions(+), 269 deletions(-) (limited to 'print.html') diff --git a/print.html b/print.html index 0f7c10f..9010bb6 100644 --- a/print.html +++ b/print.html @@ -224,11 +224,11 @@ $RBUFFER # Edit buffer content right to cursor # create zle widget which adds text right of the cursor function add-text() { - RBUFFER="some text $RBUFFER" + RBUFFER="some text $RBUFFER" } zle -N add-text -bindkey "^p" add-text +bindkey "^p" add-text

Parameter

Default value:

@@ -362,10 +362,10 @@ option should be stored.
#!/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)
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 for arg3, 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)
 
+

Command grouping

+

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
+

Argument parsing with getopts

The getopts builtin uses following global variables:

-
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).

Tags

-
  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.

#!/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
 
@@ -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

Substitute lines

# Substitute by regex.
@@ -2662,6 +2687,20 @@ echo -e 'aafooaa\ncc' | sed 's/foo/MOOSE/'
 # BAR
 # bar
 
+ +
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, mem_lat.c provides an example which can be run as follows.

@@ -3077,7 +3116,7 @@ databases for the different intel uarchs.

corresponding uarch, just grab the family model from the procfs.

 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 some Operations. @@ -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 the expr to be 0 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)

    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);
     

    Libraries specified in LD_PRELOAD are loaded from left-to-right but @@ -4630,10 +4669,10 @@ Symbol table '.dynsym' contains 342 entries: static linking against the library. The following dump shows that the tmp program linked against lpthread will depend on the symbol version GLIBC_2.3.2, which is the default version.

    -
    > 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 libfoo which defines which symbols for which versions are exported from the ELF file.

    @@ -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;
    @@ -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}")

    Walrus operator [run]

    Walrus operator := added since python 3.8.

    @@ -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())])

    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.

    -
    python -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.
    @@ -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 @@ file /proc/bus/input/devices in the proc filesystem can be consulte

    This yields entries as follows and shows which Handlers are assigned to which Name.

    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 tshak -G to list all fields that can be used in display filters.

    @@ -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"'

    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 {

      Rendered html

      <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

      -
      <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

      -
      <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

      <p></p>      // selected
      @@ -6187,7 +6226,7 @@ window.onload = () => {
       

      Chart.js

      Minimal example with external tooltips

      Rendered html

      -
      <canvas id="myChart" style="margin:5em;"></canvas>
      +
      <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
      @@ -6617,7 +6656,7 @@ Hi ASM-World!

      References

      @@ -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
      @@ -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
      -- cgit v1.2.3