To: vim_dev@googlegroups.com Subject: Patch 8.0.0572 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0572 Problem: Building the command table requires Perl. Solution: Use a Vim script solution. (Dominique Pelle, closes #1641) Files: src/Makefile, src/create_cmdidxs.pl, src/create_cmdidxs.vim, src/ex_cmdidxs.h, src/ex_docmd.c, Filelist *** ../vim-8.0.0571/src/Makefile 2017-04-20 20:19:57.876326844 +0200 --- src/Makefile 2017-04-20 21:43:52.848100156 +0200 *************** *** 1885,1899 **** -rm -rf autom4te.cache -rm -f auto/config.status auto/config.cache ! # Run Perl to generate the Ex command lookup table. This only needs to be run ! # when a command name has been added or changed. ! # NOTE: Only works when perl and vim executables are available cmdidxs: ex_cmds.h ! if test X`perl -e "print 123"` = "X123"; then \ ! vim ex_docmd.c -c '/Beginning.*create_cmdidxs/,/End.*create_cmdidxs/! perl create_cmdidxs.pl' -c wq; \ ! else \ ! echo Cannot run Perl; \ ! fi # Re-execute this Makefile to include the new auto/config.mk produced by # configure Only used when typing "make" with a fresh auto/config.mk. --- 1885,1896 ---- -rm -rf autom4te.cache -rm -f auto/config.status auto/config.cache ! # Run vim script to generate the Ex command lookup table. ! # This only needs to be run when a command name has been added or changed. ! # If this fails because you don't have Vim yet, first build and install Vim ! # without changes. cmdidxs: ex_cmds.h ! vim -u NONE -i NONE -X -S create_cmdidxs.vim # Re-execute this Makefile to include the new auto/config.mk produced by # configure Only used when typing "make" with a fresh auto/config.mk. *** ../vim-8.0.0571/src/create_cmdidxs.pl 2017-03-26 21:46:23.349430081 +0200 --- src/create_cmdidxs.pl 1970-01-01 01:00:00.000000000 +0100 *************** *** 1,75 **** - #!/usr/bin/perl -w - # - # This script generates the tables cmdidxs1[] and cmdidxs2[][] which, - # given a Ex command, determine the first value to probe to find - # a matching command in cmdnames[] based on the first character - # and the first 2 characters of the command. - # This is used to speed up lookup in cmdnames[]. - # - # Script should be run every time new Ex commands are added in Vim, - # from the src/vim directory, since it reads commands from "ex_cmds.h". - - use strict; - - # Find the list of Vim commands from cmdnames[] table in ex_cmds.h - my @cmds; - my $skipped_cmds; - open(IN, "< ex_cmds.h") or die "can't open ex_cmds.h: $!\n"; - while () { - if (/^EX\(CMD_\S*,\s*"([a-z][^"]*)"/) { - push @cmds, $1; - } elsif (/^EX\(CMD_/) { - ++$skipped_cmds; - } - } - - my %cmdidxs1; - my %cmdidxs2; - - for (my $i = $#cmds; $i >= 0; --$i) { - my $cmd = $cmds[$i]; - my $c1 = substr($cmd, 0, 1); # First character of command. - - $cmdidxs1{$c1} = $i; - - if (length($cmd) > 1) { - my $c2 = substr($cmd, 1, 1); # Second character of command. - $cmdidxs2{$c1}{$c2} = $i if (('a' lt $c2) and ($c2 lt 'z')); - } - } - - print "/* Beginning of automatically generated code by create_cmdidxs.pl\n", - " *\n", - " * Table giving the index of the first command in cmdnames[] to lookup\n", - " * based on the first letter of a command.\n", - " */\n", - "static const unsigned short cmdidxs1[26] =\n{\n", - join(",\n", map(" /* $_ */ $cmdidxs1{$_}", ('a' .. 'z'))), - "\n};\n", - "\n", - "/*\n", - " * Table giving the index of the first command in cmdnames[] to lookup\n", - " * based on the first 2 letters of a command.\n", - " * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they\n", - " * fit in a byte.\n", - " */\n", - "static const unsigned char cmdidxs2[26][26] =\n", - "{ /* a b c d e f g h i j k l m n o p q r s t u v w x y z */\n"; - for my $c1 ('a' .. 'z') { - print " /* $c1 */ {"; - for my $c2 ('a' .. 'z') { - if (exists $cmdidxs2{$c1}{$c2}) { - printf "%3d,", $cmdidxs2{$c1}{$c2} - $cmdidxs1{$c1}; - } else { - printf " 0,"; - } - } - print " }"; - print "," unless ($c1 eq 'z'); - print "\n"; - } - print "};\n", - "\n", - "static const int command_count = ", scalar(@cmds) + $skipped_cmds, ";\n", - "\n", - "/* End of automatically generated code by create_cmdidxs.pl */\n"; --- 0 ---- *** ../vim-8.0.0571/src/create_cmdidxs.vim 2017-04-20 21:53:05.012503522 +0200 --- src/create_cmdidxs.vim 2017-04-20 21:41:04.777180180 +0200 *************** *** 0 **** --- 1,81 ---- + " This script generates the tables cmdidxs1[] and cmdidxs2[][] which, + " given a Ex command, determine the first value to probe to find + " a matching command in cmdnames[] based on the first character + " and the first 2 characters of the command. + " This is used to speed up lookup in cmdnames[]. + " + " Script should be run every time new Ex commands are added in Vim, + " from the src/vim directory, since it reads commands from "ex_cmds.h". + + let cmds = [] + let skipped_cmds = 0 + + for line in readfile('ex_cmds.h') + if line =~ '^EX(CMD_' + let m = matchlist(line, '^EX(CMD_\S*,\s*"\([a-z][^"]*\)"') + if len(m) >= 2 + let cmds += [ m[1] ] + else + let skipped_cmds += 1 + endif + endif + endfor + + let cmdidxs1 = {} + let cmdidxs2 = {} + + for i in range(len(cmds) - 1, 0, -1) + let cmd = cmds[i] + let c1 = cmd[0] " First character of command + let c2 = cmd[1] " Second character of command (if any) + + let cmdidxs1{c1} = i + if c2 >= 'a' && c2 <= 'z' + let cmdidxs2{c1}{c2} = i + endif + endfor + + let output = [ '/* Automatically generated code by create_cmdidxs.vim' ] + let output += [ ' *' ] + let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ] + let output += [ ' * based on the first letter of a command.' ] + let output += [ ' */' ] + let output += [ 'static const unsigned short cmdidxs1[26] =' ] + let output += [ '{' ] + + let a_to_z = map(range(char2nr('a'), char2nr('z')), 'nr2char(v:val)') + for c1 in a_to_z + let line = ' /* ' . c1 . ' */ ' . cmdidxs1{c1} . ((c1 == 'z') ? '' : ',') + let output += [ line ] + endfor + let output += [ '};' ] + let output += [ '' ] + let output += [ '/*' ] + let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ] + let output += [ ' * based on the first 2 letters of a command.' ] + let output += [ ' * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they' ] + let output += [ ' * fit in a byte.' ] + let output += [ ' */' ] + let output += [ 'static const unsigned char cmdidxs2[26][26] =' ] + let output += [ '{ /* a b c d e f g h i j k l m n o p q r s t u v w x y z */' ] + + for c1 in a_to_z + let line = ' /* ' . c1 . ' */ {' + for c2 in a_to_z + if exists('cmdidxs2{c1}{c2}') + let line .= printf('%3d', cmdidxs2{c1}{c2} - cmdidxs1{c1}) + else + let line .= ' 0' + endif + let line .= (c2 == 'z') ? '' : ',' + endfor + let line .= ' }' . ((c1 == 'z') ? '' : ',') + let output += [ line ] + endfor + + let output += [ '};' ] + let output += [ '' ] + let output += [ 'static const int command_count = ' . (len(cmds) + skipped_cmds) . ';' ] + + call writefile(output, "ex_cmdidxs.h") + quit *** ../vim-8.0.0571/src/ex_cmdidxs.h 2017-04-20 21:53:05.020503470 +0200 --- src/ex_cmdidxs.h 2017-04-20 21:43:59.844054518 +0200 *************** *** 0 **** --- 1,72 ---- + /* Automatically generated code by create_cmdidxs.vim + * + * Table giving the index of the first command in cmdnames[] to lookup + * based on the first letter of a command. + */ + static const unsigned short cmdidxs1[26] = + { + /* a */ 0, + /* b */ 19, + /* c */ 42, + /* d */ 103, + /* e */ 125, + /* f */ 145, + /* g */ 161, + /* h */ 167, + /* i */ 176, + /* j */ 194, + /* k */ 196, + /* l */ 201, + /* m */ 259, + /* n */ 277, + /* o */ 297, + /* p */ 309, + /* q */ 348, + /* r */ 351, + /* s */ 370, + /* t */ 437, + /* u */ 472, + /* v */ 483, + /* w */ 501, + /* x */ 516, + /* y */ 525, + /* z */ 526 + }; + + /* + * Table giving the index of the first command in cmdnames[] to lookup + * based on the first 2 letters of a command. + * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they + * fit in a byte. + */ + static const unsigned char cmdidxs2[26][26] = + { /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ + /* a */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 7, 15, 0, 16, 0, 0, 0, 0, 0 }, + /* b */ { 2, 0, 0, 4, 5, 7, 0, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 13, 0, 0, 0, 0, 22, 0, 0, 0 }, + /* c */ { 3, 10, 12, 14, 16, 18, 21, 0, 0, 0, 0, 29, 33, 36, 42, 51, 53, 54, 55, 0, 57, 0, 60, 0, 0, 0 }, + /* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 6, 15, 0, 16, 0, 0, 17, 0, 0, 19, 20, 0, 0, 0, 0, 0, 0, 0 }, + /* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0 }, + /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0 }, + /* g */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 4, 5, 0, 0, 0, 0 }, + /* h */ { 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* i */ { 1, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 13, 0, 15, 0, 0, 0, 0, 0 }, + /* j */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }, + /* k */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* l */ { 3, 9, 11, 15, 16, 20, 23, 28, 0, 0, 0, 30, 33, 36, 40, 46, 0, 48, 57, 49, 50, 54, 56, 0, 0, 0 }, + /* m */ { 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16 }, + /* n */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0 }, + /* o */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 5, 0, 0, 0, 0, 0, 0, 9, 0, 11, 0, 0, 0 }, + /* p */ { 1, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 16, 17, 26, 0, 27, 0, 28, 0 }, + /* q */ { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* r */ { 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 18, 0, 0, 0, 0 }, + /* s */ { 2, 6, 15, 0, 18, 22, 0, 24, 25, 0, 0, 28, 30, 34, 38, 40, 0, 48, 0, 49, 0, 61, 62, 0, 63, 0 }, + /* t */ { 2, 0, 19, 0, 22, 23, 0, 24, 0, 25, 0, 26, 27, 28, 29, 30, 0, 31, 33, 0, 34, 0, 0, 0, 0, 0 }, + /* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* v */ { 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 12, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0 }, + /* w */ { 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 8, 0, 9, 10, 0, 12, 0, 13, 14, 0, 0, 0, 0 }, + /* x */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0 }, + /* y */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }; + + static const int command_count = 539; *** ../vim-8.0.0571/src/ex_docmd.c 2017-03-27 23:02:03.392337316 +0200 --- src/ex_docmd.c 2017-04-20 21:41:04.781180154 +0200 *************** *** 494,574 **** */ #define DO_DECLARE_EXCMD #include "ex_cmds.h" ! ! /* Beginning of automatically generated code by create_cmdidxs.pl ! * ! * Table giving the index of the first command in cmdnames[] to lookup ! * based on the first letter of a command. ! */ ! static const unsigned short cmdidxs1[26] = ! { ! /* a */ 0, ! /* b */ 19, ! /* c */ 42, ! /* d */ 103, ! /* e */ 125, ! /* f */ 145, ! /* g */ 161, ! /* h */ 167, ! /* i */ 176, ! /* j */ 194, ! /* k */ 196, ! /* l */ 201, ! /* m */ 259, ! /* n */ 277, ! /* o */ 297, ! /* p */ 309, ! /* q */ 348, ! /* r */ 351, ! /* s */ 370, ! /* t */ 437, ! /* u */ 472, ! /* v */ 483, ! /* w */ 501, ! /* x */ 516, ! /* y */ 525, ! /* z */ 526 ! }; ! ! /* ! * Table giving the index of the first command in cmdnames[] to lookup ! * based on the first 2 letters of a command. ! * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they ! * fit in a byte. ! */ ! static const unsigned char cmdidxs2[26][26] = ! { /* a b c d e f g h i j k l m n o p q r s t u v w x y z */ ! /* a */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 7, 15, 0, 16, 0, 0, 0, 0, 0, }, ! /* b */ { 0, 0, 0, 4, 5, 7, 0, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, 13, 0, 0, 0, 0, 22, 0, 0, 0, }, ! /* c */ { 0, 10, 12, 14, 16, 18, 21, 0, 0, 0, 0, 29, 33, 36, 42, 51, 53, 54, 55, 0, 57, 0, 60, 0, 0, 0, }, ! /* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 6, 15, 0, 16, 0, 0, 17, 0, 0, 19, 20, 0, 0, 0, 0, 0, 0, 0, }, ! /* e */ { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, }, ! /* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, }, ! /* g */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 4, 5, 0, 0, 0, 0, }, ! /* h */ { 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, ! /* i */ { 0, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 13, 0, 15, 0, 0, 0, 0, 0, }, ! /* j */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, }, ! /* k */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, ! /* l */ { 0, 9, 11, 15, 16, 20, 23, 28, 0, 0, 0, 30, 33, 36, 40, 46, 0, 48, 57, 49, 50, 54, 56, 0, 0, 0, }, ! /* m */ { 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, ! /* n */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 0, 0, 0, 0, 0, 17, 0, 0, 0, 0, 0, }, ! /* o */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 5, 0, 0, 0, 0, 0, 0, 9, 0, 11, 0, 0, 0, }, ! /* p */ { 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 16, 17, 26, 0, 27, 0, 28, 0, }, ! /* q */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, ! /* r */ { 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 18, 0, 0, 0, 0, }, ! /* s */ { 0, 6, 15, 0, 18, 22, 0, 24, 25, 0, 0, 28, 30, 34, 38, 40, 0, 48, 0, 49, 0, 61, 62, 0, 63, 0, }, ! /* t */ { 0, 0, 19, 0, 22, 23, 0, 24, 0, 25, 0, 26, 27, 28, 29, 30, 0, 31, 33, 0, 34, 0, 0, 0, 0, 0, }, ! /* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, ! /* v */ { 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 9, 12, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, }, ! /* w */ { 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 0, 0, 8, 0, 9, 10, 0, 12, 0, 13, 14, 0, 0, 0, 0, }, ! /* x */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, }, ! /* y */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, ! /* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } ! }; ! ! static const int command_count = 539; ! ! /* End of automatically generated code by create_cmdidxs.pl */ static char_u dollar_command[2] = {'$', 0}; --- 494,500 ---- */ #define DO_DECLARE_EXCMD #include "ex_cmds.h" ! #include "ex_cmdidxs.h" static char_u dollar_command[2] = {'$', 0}; *************** *** 3046,3052 **** --- 2972,2981 ---- doend: if (curwin->w_cursor.lnum == 0) /* can happen with zero line number */ + { curwin->w_cursor.lnum = 1; + curwin->w_cursor.col = 0; + } if (errormsg != NULL && *errormsg != NUL && !did_emsg) { *** ../vim-8.0.0571/Filelist 2017-04-20 20:19:57.880326819 +0200 --- Filelist 2017-04-20 21:47:41.202611421 +0200 *************** *** 24,29 **** --- 24,30 ---- src/edit.c \ src/eval.c \ src/evalfunc.c \ + src/ex_cmdidxs.h \ src/ex_cmds.c \ src/ex_cmds.h \ src/ex_cmds2.c \ *************** *** 215,221 **** src/config.mk.in \ src/configure \ src/configure.ac \ ! src/create_cmdidxs.pl \ src/gui_at_fs.c \ src/gui_at_sb.c \ src/gui_at_sb.h \ --- 216,222 ---- src/config.mk.in \ src/configure \ src/configure.ac \ ! src/create_cmdidxs.vim \ src/gui_at_fs.c \ src/gui_at_sb.c \ src/gui_at_sb.h \ *** ../vim-8.0.0571/src/version.c 2017-04-20 21:12:26.592211591 +0200 --- src/version.c 2017-04-20 21:40:15.597494696 +0200 *************** *** 766,767 **** --- 766,769 ---- { /* Add new patch number below this line */ + /**/ + 572, /**/ -- A poem: read aloud: <> !*''# Waka waka bang splat tick tick hash, ^"`$$- Caret quote back-tick dollar dollar dash, !*=@$_ Bang splat equal at dollar under-score, %*<> ~#4 Percent splat waka waka tilde number four, &[]../ Ampersand bracket bracket dot dot slash, |{,,SYSTEM HALTED Vertical-bar curly-bracket comma comma CRASH. Fred Bremmer and Steve Kroese (Calvin College & Seminary of Grand Rapids, MI.) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///