From cef9f4d752deb40315753d89bb97fe111200a018 Mon Sep 17 00:00:00 2001 From: sepehr Date: Thu, 25 Jul 2019 23:13:24 -0700 Subject: [PATCH] Modifications to work with kernel 4.4.0. Verions >= 3.17 and < 5 might work as well. Performance side effects include: -some inline functions replaced with declarations and definitions. note: previously caused error during click-install with kernel moduels, "error: unknown symbols". -removed template<> from hashcode.hh --- doc/testie.1 | 347 ++++++++++++++++-------------- elements/icmp/icmppingrewriter.cc | 8 + elements/icmp/icmppingrewriter.hh | 8 +- elements/ip/ipaddrpairrewriter.cc | 8 + elements/ip/ipaddrpairrewriter.hh | 8 +- elements/ip/ipaddrrewriter.cc | 8 + elements/ip/ipaddrrewriter.hh | 10 +- elements/linuxmodule/fromhost.cc | 11 +- elements/tcpudp/iprewriter.cc | 14 +- elements/tcpudp/iprewriter.hh | 12 +- elements/tcpudp/tcprewriter.cc | 8 + elements/tcpudp/tcprewriter.hh | 8 +- elements/tcpudp/udprewriter.cc | 8 + elements/tcpudp/udprewriter.hh | 8 +- include/click/cxxprotect.h | 3 +- include/click/hashcode.hh | 14 +- include/click/string.hh | 13 +- include/click/timestamp.hh | 16 +- lib/string.cc | 9 + lib/timestamp.cc | 14 ++ linuxmodule/click-linuxtool.pl | 28 ++- linuxmodule/proclikefs.c | 15 +- 22 files changed, 328 insertions(+), 250 deletions(-) diff --git a/doc/testie.1 b/doc/testie.1 index d368d591fa..c55295190f 100644 --- a/doc/testie.1 +++ b/doc/testie.1 @@ -1,4 +1,4 @@ -.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16) +.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== @@ -38,6 +38,8 @@ . ds PI \(*p . ds L" `` . ds R" '' +. ds C` +. ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. @@ -48,17 +50,24 @@ .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. -.ie \nF \{\ -. de IX -. tm Index:\\$1\t\\n%\t"\\$2" +.\" +.\" Avoid warning from groff about undefined register 'F'. +.de IX .. -. nr % 0 -. rr F -.\} -.el \{\ -. de IX +.nr rF 0 +.if \n(.g .if rF .nr rF 1 +.if (\n(rF:(\n(.g==0)) \{ +. if \nF \{ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" .. +. if !\nF==2 \{ +. nr % 0 +. nr F 2 +. \} +. \} .\} +.rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. @@ -124,7 +133,7 @@ .\" ======================================================================== .\" .IX Title "TESTIE 1" -.TH TESTIE 1 "2013-06-19" "perl v5.14.2" "" +.TH TESTIE 1 "2019-07-25" "perl v5.18.2" "" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l @@ -133,214 +142,230 @@ testie \- simple test harness .SH "SYNOPSIS" .IX Header "SYNOPSIS" -.Vb 1 -\& testie [OPTIONS] [FILE]... -.Ve +testie [\s-1OPTIONS\s0] [\s-1FILE\s0]... .SH "DESCRIPTION" .IX Header "DESCRIPTION" -Testie is a simple test harness. Each testie test file incorporates a shell -script to be run and, optionally, input and expected output files for that -script. Testie runs the script; the test fails if any of the script -commands fail, or if the script generates unexpected output. +Testie is a simple test harness. A testie test comprises a shell +script and, optionally, input and expected output files for that +script. Testie runs the script; the test succeeds if all of the script +commands succeed, and the actual output files match expectations. .PP -To run testie, pass it one or more test filenames. It will print useful -error messages for failed tests. Alternatively, give it directory names; -the directories are recursively searched for '\fI*.testie\fR' files. +Testie accepts test filenames and directories as arguments. +Directories are recursively searched for \fI*.testie\fR files. It +reports problems for failed tests, plus a summary. .PP -Return status is 0 if all tests succeed, 1 if any test fails, and 2 if a -test fails due to an internal error. Tests whose \f(CW%require\fR prerequisites -fail do not affect the return status, except that if all tests' -prerequisites fail, the return status is 1 instead of 0. +Testie exits with status 0 if all tests succeed, 1 if any test fails, +and 2 if a test fails due to an internal error. Tests whose \fB\f(CB%require\fB\fR +prerequisites fail do not affect the exit status, except that if all +tests' prerequisites fail, the return status is 1 instead of 0. .SH "OPTIONS" .IX Header "OPTIONS" +.IP "\fB\-j\fR\fIN\fR, \fB\-\-jobs\fR=\fIN\fR" 8 +.IX Item "-jN, --jobs=N" +Run up to \fIN\fR tests simultaneously. Like Make's \fB\-j\fR option. .IP "\fI\s-1VARIABLE\s0\fR=\fI\s-1VALUE\s0\fR" 8 .IX Item "VARIABLE=VALUE" Provide an environment variable setting for \fI\s-1VARIABLE\s0\fR within the script. -.IP "\-V, \-\-verbose" 8 +.IP "\fB\-s\fR, \fB\-\-show\fR \fI\s-1FILE\s0\fR" 8 +.IX Item "-s, --show FILE" +Echo the contents of \fI\s-1FILE\s0\fR on completion. \fI\s-1FILE\s0\fR should be one of the +filenames specified by \fB\f(CB%file\fB\fR or \fB\f(CB%expect\fB\fR, or \fBstdout\fR or \fBstderr\fR. +Leaves out any ignored lines. +.IP "\fB\-S\fR, \fB\-\-show\-raw\fR \fI\s-1FILE\s0\fR" 8 +.IX Item "-S, --show-raw FILE" +Like \fB\-\-show\fR, but includes any ignored lines. +.IP "\fB\-\-show\-all\fR" 8 +.IX Item "--show-all" +Calls \fB\-\-show\fR for all filenames specified by any \fB\f(CB%expect\fB\fR, plus \fBstdout\fR +and \fBstderr\fR. Leaves out any ignored lines. +.IP "\fB\-\-show\-all\-raw\fR" 8 +.IX Item "--show-all-raw" +Like \fB\-\-show\-all\fR, but includes any ignored lines. +.IP "\fB\-e\fR, \fB\-\-expand\fR" 8 +.IX Item "-e, --expand" +Don't run the given test; instead, expand its files into the current +directory. The script is stored in a file called \fI\f(CI%script\fI\fR. +.IP "\fB\-\-preserve\-temporaries\fR" 8 +.IX Item "--preserve-temporaries" +Preserve temporary test directories. Testie runs each test in its own +subdirectory of the current directory. Test directories are named +\&\fItestieNNNNN\fR, and are typically removed on test completion. +Examining the contents of a test directory can be useful when +debugging a test. +.IP "\fB\-p\fR, \fB\-\-path\fR \fI\s-1DIR\s0\fR" 8 +.IX Item "-p, --path DIR" +Prepend \fI\s-1DIR\s0\fR to the \f(CW\*(C`PATH\*(C'\fR environment variable before running the +test script. +.IP "\fB\-V\fR, \fB\-\-verbose\fR" 8 .IX Item "-V, --verbose" Print information to standard error about successful tests as well as unsuccessful tests. -.IP "\-VV, \-\-superverbose" 8 +.IP "\fB\-VV\fR, \fB\-\-superverbose\fR" 8 .IX Item "-VV, --superverbose" -Like \-\-verbose, but use a slightly different format, and additionally print -every test's \f(CW%info\fR section before the test results. -.IP "\-q, \-\-quiet" 8 +Like \fB\-\-verbose\fR, but use a slightly different format, and +additionally print every test's \fB\f(CB%info\fB\fR section before the test results. +.IP "\fB\-q\fR, \fB\-\-quiet\fR" 8 .IX Item "-q, --quiet" Don't print information to the terminal while running multiple tests. -.IP "\-v, \-\-version" 8 +.IP "\fB\-v\fR, \fB\-\-version\fR" 8 .IX Item "-v, --version" Print version number information and exit. -.IP "\-\-help" 8 +.IP "\fB\-\-help\fR" 8 .IX Item "--help" Print help information and exit. -.IP "\-\-preserve\-temporaries" 8 -.IX Item "--preserve-temporaries" -Preserve the temporary directory created for the test. -.IP "\-s, \-\-show \s-1FILE\s0" 8 -.IX Item "-s, --show FILE" -Echo the contents of \s-1FILE\s0 on completion. \s-1FILE\s0 should be one of the -filenames specified by \f(CW%file\fR or \f(CW%expect\fR*, or 'stdout' or 'stderr'. -Leaves out any ignored lines. -.IP "\-S, \-\-show\-raw \s-1FILE\s0" 8 -.IX Item "-S, --show-raw FILE" -Like \-\-show, but includes any ignored lines. -.IP "\-\-show\-all" 8 -.IX Item "--show-all" -Like '\-\-show' for all filenames specified by any \f(CW%expect\fR*, plus 'stdout' -and 'stderr'. Leaves out any ignored lines. -.IP "\-\-show\-all\-raw" 8 -.IX Item "--show-all-raw" -Like '\-\-show\-raw' for all filenames specified by any \f(CW%expect\fR*, -plus 'stdout' and 'stderr'. Includes any ignored lines. -.IP "\-e, \-\-expand" 8 -.IX Item "-e, --expand" -Don't run the given test; instead, expand its files into the current -directory. The script is stored in a file called '+script+'. -.IP "\-j\fIN\fR, \-\-jobs=\fIN\fR" 8 -.IX Item "-jN, --jobs=N" -Run up to \fIN\fR tests simultaneously. Like Make's '\-j' option. .SH "FILE FORMAT" .IX Header "FILE FORMAT" Testie test files consist of several sections, each introduced by a line -starting with %. There must be, at least, a \f(CW%script\fR section. -.PP -The \f(CW%file\fR and \f(CW%expect\fR* sections define input and/or output files by -name. Testie runs its script in a private directory in \fI/tmp\fR; any files -mentioned in \f(CW%file\fR or \f(CW%expect\fR* are placed in that directory. -.ie n .IP "%script" 8 -.el .IP "\f(CW%script\fR" 8 +starting with \fB%\fR. There must be, at least, a \fB\f(CB%script\fB\fR section. +The \fB\f(CB%file\fB\fR and \fB\f(CB%expect\fB\fR sections define input and output files by +name. +.ie n .IP "\fB\fB%script\fB\fR" 8 +.el .IP "\fB\f(CB%script\fB\fR" 8 .IX Item "%script" -The shell script (in sh syntax) that controls the test. Testie will run -each command in sequence. Every command in the script must succeed, with -exit status 0, or the test will fail. Use \f(CW%file\fR sections to define script -input files and \f(CW%expect\fR* sections to check script output files for expected -values. +The \fBsh\fR shell script that controls the test. Testie will run each +command in sequence. Every command in the script must succeed, with +exit status 0, or the test will fail. Use \fB\f(CB%file\fB\fR sections to define +script input files and \fB\f(CB%expect\fB\fR sections to check script output files +for expected values. +.Sp +The \fB\f(CB%script\fB\fR section can contain subtests. To start a new subtest, +execute a command like \f(CW\*(C`testie_subtest\ SECTIONNAME\*(C'\fR. Testie will +report the problematic \f(CW\*(C`SECTIONNAME\*(C'\fR when standard output or error +doesn't match an expected value. .Sp -The \f(CW%script\fR section can contain multiple subtests. To start a new subtest, -execute a command like \*(L"testie_subtest \s-1SECTIONNAME\s0\*(R". Testie will report the -offending \s-1SECTIONNAME\s0 when standard output or error doesn't match an -expected value. -.ie n .IP "%require [\-q]" 8 -.el .IP "\f(CW%require\fR [\-q]" 8 +The script's environment is populated with any \fI\s-1VARIABLE\s0\fRs set on the +testie command line with \fB\f(BI\s-1VARIABLE\s0\fB=\f(BI\s-1VALUE\s0\fB\fR syntax. Also, the +\&\fB\f(CB$rundir\fB\fR environment variable is set to the directory in which +testie was originally run. +.ie n .IP "\fB\fB%require\fB [\-q]\fR" 8 +.el .IP "\fB\f(CB%require\fB [\-q]\fR" 8 .IX Item "%require [-q]" -A shell script (in sh syntax) defining prerequisites that must be satisfied +An \fBsh\fR shell script defining prerequisites that must be satisfied before the test can run. Every command in the script must succeed, with exit status 0, for the test to run. Standard output and error are not -checked, however. The \f(CW\*(C`\-q\*(C'\fR flag tells testie not to print an error message +checked, however. The \fB\-q\fR flag tells testie not to print an error message if a requirement fails. .Sp Testie runs the requirement script before creating any other test files. -For example, contents of \f(CW%file\fR sections are not available. -.ie n .IP "%info" 8 -.el .IP "\f(CW%info\fR" 8 +For example, contents of \fB\f(CB%file\fB\fR sections are not available. +.ie n .IP "\fB\fB%info\fB\fR" 8 +.el .IP "\fB\f(CB%info\fB\fR" 8 .IX Item "%info" -A short description of the test. In \-\-superverbose mode, the first +A short description of the test. In \fB\-\-superverbose\fR mode, the first paragraph of its contents is printed before the test results. -.ie n .IP "%cut" 8 -.el .IP "\f(CW%cut\fR" 8 +.ie n .IP "\fB\fB%cut\fB\fR" 8 +.el .IP "\fB\f(CB%cut\fB\fR" 8 .IX Item "%cut" This section is ignored. It is intended to comment out obsolete parts of the test. -.ie n .IP "%file [\-d] [+LENGTH] \s-1FILENAME\s0..." 8 -.el .IP "\f(CW%file\fR [\-d] [+LENGTH] \s-1FILENAME\s0..." 8 -.IX Item "%file [-d] [+LENGTH] FILENAME..." -Create an input file for the script. \s-1FILENAME\s0 can be 'stdin', which sets -the script's standard input. If \s-1LENGTH\s0 is provided, the file data consists -of the \s-1LENGTH\s0 bytes following this line. Otherwise, it consists of the data -up to the next section. The \f(CW\*(C`\-d\*(C'\fR flag tells testie to delete the -first character of each line in the section; this makes it possible to -include files that have lines that start with %. -.ie n .IP "%expectv [\-ad] [+LENGTH] \s-1FILENAME\s0..." 8 -.el .IP "\f(CW%expectv\fR [\-ad] [+LENGTH] \s-1FILENAME\s0..." 8 -.IX Item "%expectv [-ad] [+LENGTH] FILENAME..." -An expected output file for the script. \s-1FILENAME\s0 can be 'stdout', for -standard output. If \s-1LENGTH\s0 is provided, the file data consists of the -\&\s-1LENGTH\s0 bytes following this line; otherwise, it consists of the data up to -the next section. +.ie n .IP "\fB\fB%file\fB [\-de] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8 +.el .IP "\fB\f(CB%file\fB [\-de] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8 +.IX Item "%file [-de] [+LENGTH] FILENAME..." +Create an input file for the script. \fI\s-1FILENAME\s0\fR can be \fBstdin\fR, +which sets the script's standard input. If \fB+\fR\fI\s-1LENGTH\s0\fR is provided, +the file data consists of the \fI\s-1LENGTH\s0\fR bytes following this line; +otherwise, it consists of the data up to the next section. The \fB\-d\fR +flag tells testie to delete the first character of each line in the +section. The \fB\-e\fR flag indicates that the section was \s-1MIME\s0 +Base64\-encoded (see \fIbase64\fR\|(1)); it is decoded before use. To +include a file with lines that start with \fB%\fR (which would normally +start a new section), use \fB\-d\fR and preface each line of the file with +a space, or use \fB\-e\fR. +.ie n .IP "\fB\fB%expect\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8 +.el .IP "\fB\f(CB%expect\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8 +.IX Item "%expect [-adeiw] [+LENGTH] FILENAME..." +Define an expected output file. Differences between the script's +output \fI\s-1FILENAME\s0\fR and the contents of the \fB\f(CB%expect\fB\fR section will +cause the test to fail. .Sp -Testie will run the script, then compare the script's output file with the -provided data. They must match exactly or the test fails. +\&\fI\s-1FILENAME\s0\fR can be \fBstdout\fR, for standard output. If \fB+\fR\fI\s-1LENGTH\s0\fR is +provided, the file data consists of the \fI\s-1LENGTH\s0\fR bytes following this +line; otherwise, it consists of the data up to the next section. .Sp -The \f(CW\*(C`\-a\*(C'\fR flag marks this expected output as an alternate. Testie will -compare the script's output file with each provided alternate; the test -succeeds if any of the alternates match. The \f(CW\*(C`\-d\*(C'\fR flag behaves as in -\&\f(CW%file\fR. -.ie n .IP "%expect [\-adiw] [+LENGTH] \s-1FILENAME\s0..." 8 -.el .IP "\f(CW%expect\fR [\-adiw] [+LENGTH] \s-1FILENAME\s0..." 8 -.IX Item "%expect [-adiw] [+LENGTH] FILENAME..." -An expected output file for the script. Arguments are as for \f(CW%expectv\fR. +After running the script, testie compares the \fI\s-1FILENAME\s0\fR generated by +the script with the provided data. The files are compared +line-by-line. Testie ignores blank lines, differences in trailing +whitespace, and lines in the script output that match \fB\f(CB%ignore\fB\fR +patterns (see below). The \fB\-w\fR flag causes testie to ignore +differences in amount of whitespace within each line. .Sp -Testie will run the script, then compare the file generated by script -with the provided data. The files are compared line-by-line. Testie -ignores blank lines and trailing whitespace on each line. It also -ignores lines in the script output that match \f(CW%ignore\fR patterns (see below). -\&\f(CW%expect\fR lines can contain Perl regular expressions, enclosed by two -sets of braces; so the \f(CW%expect\fR line +\&\fB\f(CB%expect\fB\fR lines can contain Perl regular expressions, enclosed by two +sets of braces. The \fB\f(CB%expect\fB\fR line .Sp .Vb 1 \& foo{{(bar)?}} .Ve .Sp -matches either 'foo' or 'foobar'. +matches either \f(CW\*(C`foo\*(C'\fR or \f(CW\*(C`foobar\*(C'\fR. The \fB\-i\fR flag makes all such +regular expressions case-insensitive. (Text outside of regular +expressions must match case.) .Sp -Document an \f(CW%expect\fR line with \*(L"{{?comment}}\*(R" blocks. For example: +Document an \fB\f(CB%expect\fB\fR line with \f(CW\*(C`{{?comment}}\*(C'\fR blocks. For example: .Sp .Vb 1 \& foo {{? the sort was in the right order}} .Ve .Sp -Testie ignores whitespace before and after the \*(L"{{?comment}}\*(R" block, and if +Testie ignores whitespace before and after the \f(CW\*(C`{{?comment}}\*(C'\fR block, and if the actual output differs from this expected line, it prints the comment in addition to the line differences. .Sp -The \f(CW\*(C`\-a\*(C'\fR and \f(CW\*(C`\-d\*(C'\fR flags may also be used for \f(CW%expect\fR sections. Also, the -\&\f(CW\*(C`\-i\*(C'\fR flag makes any regular expressions case-insensitive (text outside of -regular expressions must match case), and the \f(CW\*(C`\-w\*(C'\fR flag ignores any -differences in amount of whitespace within a line. -.ie n .IP "%expectx [\-adiw] [+LENGTH] \s-1FILENAME\s0..." 8 -.el .IP "\f(CW%expectx\fR [\-adiw] [+LENGTH] \s-1FILENAME\s0..." 8 +The \fB\-a\fR flag marks this expected output as an alternate. Testie will +compare the script's output file with each provided alternate; the +test succeeds if any of the alternates match. The \fB\-d\fR flag behaves +as in \fB\f(CB%file\fB\fR. +.ie n .IP "\fB\fB%expectv\fB [\-ade] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8 +.el .IP "\fB\f(CB%expectv\fB [\-ade] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8 +.IX Item "%expectv [-ade] [+LENGTH] FILENAME..." +Define a literal expected output file. This behaves like \fB\f(CB%expect\fB\fR, +except that the script's output file must match the provided data +\&\fIexactly\fR: \fB\f(CB%expectv\fB\fR never ignores whitespace differences, does not +treat \f(CW\*(C`{{}}\*(C'\fR blocks as regular expressions, and does not parse +\&\fB\f(CB%ignore\fB\fR patterns. +.ie n .IP "\fB\fB%expectx\fB [\-adiw] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8 +.el .IP "\fB\f(CB%expectx\fB [\-adiw] [+\f(BI\s-1LENGTH\s0\fB] \f(BI\s-1FILENAME\s0\fB...\fR" 8 .IX Item "%expectx [-adiw] [+LENGTH] FILENAME..." -\&\f(CW%expectx\fR is just like \f(CW%expect\fR, except that every line is treated as a -regular expression. The input is parsed for \*(L"{{?comment}}\*(R" blocks, but -other brace pairs are treated according to the normal regular expression -rules. -.ie n .IP "%stdin [+LENGTH]" 8 -.el .IP "\f(CW%stdin\fR [+LENGTH]" 8 -.IX Item "%stdin [+LENGTH]" -Same as '%file stdin [\s-1ARGS\s0]'. -.ie n .IP "%stdout [\-adiw] [+LENGTH]" 8 -.el .IP "\f(CW%stdout\fR [\-adiw] [+LENGTH]" 8 -.IX Item "%stdout [-adiw] [+LENGTH]" -Same as '%expect stdout'. -.ie n .IP "%stderr [\-adiw] [+LENGTH]" 8 -.el .IP "\f(CW%stderr\fR [\-adiw] [+LENGTH]" 8 -.IX Item "%stderr [-adiw] [+LENGTH]" -Same as '%expect stderr'. -.ie n .IP "%ignorex [\-di] [+LENGTH] [\s-1FILENAME\s0]" 8 -.el .IP "\f(CW%ignorex\fR [\-di] [+LENGTH] [\s-1FILENAME\s0]" 8 +Define a regular-expression expected output file. This behaves like +\&\fB\f(CB%expect\fB\fR, except that every line is treated as a regular expression. +\&\f(CW\*(C`{{?comment}}\*(C'\fR blocks are ignored, but other brace pairs are treated +according to the normal regular expression rules. +.ie n .IP "\fB\fB%stdin\fB [\-de] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8 +.el .IP "\fB\f(CB%stdin\fB [\-de] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8 +.IX Item "%stdin [-de] [+LENGTH]" +Same as \fB\f(CB%file\fB stdin\fR. +.ie n .IP "\fB\fB%stdout\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8 +.el .IP "\fB\f(CB%stdout\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8 +.IX Item "%stdout [-adeiw] [+LENGTH]" +Same as \fB\f(CB%expect\fB stdout\fR. +.ie n .IP "\fB\fB%stderr\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8 +.el .IP "\fB\f(CB%stderr\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB]\fR" 8 +.IX Item "%stderr [-adeiw] [+LENGTH]" +Same as \fB\f(CB%expect\fB stderr\fR. +.ie n .IP "\fB\fB%ignorex\fB [\-di] [+\f(BI\s-1LENGTH\s0\fB] [\f(BI\s-1FILENAME\s0\fB]\fR" 8 +.el .IP "\fB\f(CB%ignorex\fB [\-di] [+\f(BI\s-1LENGTH\s0\fB] [\f(BI\s-1FILENAME\s0\fB]\fR" 8 .IX Item "%ignorex [-di] [+LENGTH] [FILENAME]" -Each line in the \f(CW%ignorex\fR section is a Perl regular expression. Lines in -the supplied \s-1FILENAME\s0 that match any of those regular expressions will not -be considered when comparing files with \f(CW%expect\fR data. The regular -expression must match the whole line. \s-1FILENAME\s0 may be 'all', in which case -the regular expressions will apply to all \f(CW%expect\fR files. \*(L"{{?comment}}\*(R" +Each line in the \fB\f(CB%ignorex\fB\fR section is a Perl regular expression. Lines in +the supplied \fI\s-1FILENAME\s0\fR that match any of those regular expressions will not +be considered when comparing files with \fB\f(CB%expect\fB\fR data. The regular +expression must match the whole line. \fI\s-1FILENAME\s0\fR may be \fBall\fR, in which case +the regular expressions will apply to all \fB\f(CB%expect\fB\fR files. \f(CW\*(C`{{?comment}}\*(C'\fR blocks are ignored. -.ie n .IP "%ignore, %ignorev" 8 -.el .IP "\f(CW%ignore\fR, \f(CW%ignorev\fR" 8 -.IX Item "%ignore, %ignorev" -Like '%ignorex', but '%ignore' parses regular expressions only inside -double braces (\*(L"{{ }}\*(R"), and '%ignorev' lines must match exactly. -.ie n .IP "%include \s-1FILENAME\s0" 8 -.el .IP "\f(CW%include\fR \s-1FILENAME\s0" 8 +.ie n .IP "\fB\fB%ignore\fB\fR, \fB\fB%ignorev\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB] [\f(BI\s-1FILENAME\s0\fB]\fR" 8 +.el .IP "\fB\f(CB%ignore\fB\fR, \fB\f(CB%ignorev\fB [\-adeiw] [+\f(BI\s-1LENGTH\s0\fB] [\f(BI\s-1FILENAME\s0\fB]\fR" 8 +.IX Item "%ignore, %ignorev [-adeiw] [+LENGTH] [FILENAME]" +Like \fB\f(CB%ignorex\fB\fR, but \fB\f(CB%ignore\fB\fR parses regular expressions only inside +double braces (\f(CW\*(C`{{ }}\*(C'\fR), and \fB\f(CB%ignorev\fB\fR lines must match exactly. +.ie n .IP "\fB\fB%include\fB \f(BI\s-1FILENAME\s0\fB\fR" 8 +.el .IP "\fB\f(CB%include\fB \f(BI\s-1FILENAME\s0\fB\fR" 8 .IX Item "%include FILENAME" Interpolate the contents of another testie file. -.ie n .IP "%eot" 8 -.el .IP "\f(CW%eot\fR" 8 +.ie n .IP "\fB\fB%eot\fB\fR" 8 +.el .IP "\fB\f(CB%eot\fB\fR" 8 .IX Item "%eot" -Marks the end of the current test. The rest of the file will be parsed for +Marks the end of the current test. The rest of the file will be parsed for additional tests. -.ie n .IP "%eof" 8 -.el .IP "\f(CW%eof\fR" 8 +.ie n .IP "\fB\fB%eof\fB\fR" 8 +.el .IP "\fB\f(CB%eof\fB\fR" 8 .IX Item "%eof" The rest of the file is ignored. .SH "EXAMPLE" @@ -360,8 +385,8 @@ file. .SH "ENVIRONMENT" .IX Header "ENVIRONMENT" By default, testie sets the \f(CW\*(C`LC_ALL\*(C'\fR environment variable to \*(L"C\*(R"; without -this setting commands like 'sort' have unpredictable effects. To set -\&\f(CW\*(C`LC_ALL\*(C'\fR to another value, set it in the \f(CW%script\fR section. +this setting commands like \fBsort\fR have unpredictable effects. To set +\&\f(CW\*(C`LC_ALL\*(C'\fR to another value, set it in the \fB\f(CB%script\fB\fR section. .SH "AUTHOR" .IX Header "AUTHOR" Eddie Kohler, diff --git a/elements/icmp/icmppingrewriter.cc b/elements/icmp/icmppingrewriter.cc index 9222cfd30d..077b0c7370 100644 --- a/elements/icmp/icmppingrewriter.cc +++ b/elements/icmp/icmppingrewriter.cc @@ -217,6 +217,14 @@ ICMPPingRewriter::add_handlers() add_rewriter_handlers(true); } +void +ICMPPingRewriter::destroy_flow(IPRewriterFlow *flow) +{ + unmap_flow(flow, _map); + static_cast(flow)->~ICMPPingFlow(); + _allocator.deallocate(flow); +} + CLICK_ENDDECLS ELEMENT_REQUIRES(IPRewriterBase) EXPORT_ELEMENT(ICMPPingRewriter) diff --git a/elements/icmp/icmppingrewriter.hh b/elements/icmp/icmppingrewriter.hh index e09dce6242..4ab679cec3 100644 --- a/elements/icmp/icmppingrewriter.hh +++ b/elements/icmp/icmppingrewriter.hh @@ -124,13 +124,7 @@ class ICMPPingRewriter : public IPRewriterBase { public: }; -inline void -ICMPPingRewriter::destroy_flow(IPRewriterFlow *flow) -{ - unmap_flow(flow, _map); - static_cast(flow)->~ICMPPingFlow(); - _allocator.deallocate(flow); -} + CLICK_ENDDECLS #endif diff --git a/elements/ip/ipaddrpairrewriter.cc b/elements/ip/ipaddrpairrewriter.cc index 05ac76f56c..29be0e99fd 100644 --- a/elements/ip/ipaddrpairrewriter.cc +++ b/elements/ip/ipaddrpairrewriter.cc @@ -183,6 +183,14 @@ IPAddrPairRewriter::add_handlers() add_rewriter_handlers(true); } +void +IPAddrPairRewriter::destroy_flow(IPRewriterFlow *flow) +{ + unmap_flow(flow, _map); + static_cast(flow)->~IPAddrPairFlow(); + _allocator.deallocate(flow); +} + ELEMENT_REQUIRES(IPRewriterBase) EXPORT_ELEMENT(IPAddrPairRewriter) CLICK_ENDDECLS diff --git a/elements/ip/ipaddrpairrewriter.hh b/elements/ip/ipaddrpairrewriter.hh index 27921a0a56..5a5559fd8a 100644 --- a/elements/ip/ipaddrpairrewriter.hh +++ b/elements/ip/ipaddrpairrewriter.hh @@ -159,13 +159,7 @@ class IPAddrPairRewriter : public IPRewriterBase { public: }; -inline void -IPAddrPairRewriter::destroy_flow(IPRewriterFlow *flow) -{ - unmap_flow(flow, _map); - static_cast(flow)->~IPAddrPairFlow(); - _allocator.deallocate(flow); -} + CLICK_ENDDECLS #endif diff --git a/elements/ip/ipaddrrewriter.cc b/elements/ip/ipaddrrewriter.cc index 868513eba2..7110d9ccf6 100644 --- a/elements/ip/ipaddrrewriter.cc +++ b/elements/ip/ipaddrrewriter.cc @@ -194,6 +194,14 @@ IPAddrRewriter::add_handlers() add_rewriter_handlers(true); } +void +IPAddrRewriter::destroy_flow(IPRewriterFlow *flow) +{ + unmap_flow(flow, _map); + static_cast(flow)->~IPAddrFlow(); + _allocator.deallocate(flow); +} + ELEMENT_REQUIRES(IPRewriterBase) EXPORT_ELEMENT(IPAddrRewriter) CLICK_ENDDECLS diff --git a/elements/ip/ipaddrrewriter.hh b/elements/ip/ipaddrrewriter.hh index edf635767b..6099ba704b 100644 --- a/elements/ip/ipaddrrewriter.hh +++ b/elements/ip/ipaddrrewriter.hh @@ -139,7 +139,7 @@ class IPAddrRewriter : public IPRewriterBase { public: int configure(Vector &conf, ErrorHandler *errh) CLICK_COLD; //void take_state(Element *, ErrorHandler *); - inline IPRewriterEntry *get_entry(int ip_p, const IPFlowID &flowid, int input); + IPRewriterEntry *get_entry(int ip_p, const IPFlowID &flowid, int input); IPRewriterEntry *add_flow(int ip_p, const IPFlowID &flowid, const IPFlowID &rewritten_flowid, int input); void destroy_flow(IPRewriterFlow *flow); @@ -158,13 +158,7 @@ class IPAddrRewriter : public IPRewriterBase { public: }; -inline void -IPAddrRewriter::destroy_flow(IPRewriterFlow *flow) -{ - unmap_flow(flow, _map); - static_cast(flow)->~IPAddrFlow(); - _allocator.deallocate(flow); -} + CLICK_ENDDECLS #endif diff --git a/elements/linuxmodule/fromhost.cc b/elements/linuxmodule/fromhost.cc index bdb0040ed5..851f055f8c 100644 --- a/elements/linuxmodule/fromhost.cc +++ b/elements/linuxmodule/fromhost.cc @@ -135,11 +135,20 @@ static void fromhost_inet_setup(struct net_device *dev) } #endif +/* include/uapi/linux/netdevice.h */ +/* interface name assignment types (sysfs name_assign_type attribute) */ +/* #define NET_NAME_UNKNOWN 0 unknown origin (not exposed to userspace) */ +/* #define NET_NAME_ENUM 1 enumerated by kernel */ +/* #define NET_NAME_PREDICTABLE 2 predictably named by the kernel */ +/* #define NET_NAME_USER 3 provided by user-space */ +/* #define NET_NAME_RENAMED 4 renamed by user-space */ net_device * FromHost::new_device(const char *name) { void (*setup)(struct net_device *) = (_macaddr ? ether_setup : fromhost_inet_setup); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0) + net_device *dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, setup); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) net_device *dev = alloc_netdev(0, name, setup); #else int errcode; diff --git a/elements/tcpudp/iprewriter.cc b/elements/tcpudp/iprewriter.cc index 0bc909b8bc..860f17f601 100644 --- a/elements/tcpudp/iprewriter.cc +++ b/elements/tcpudp/iprewriter.cc @@ -73,7 +73,7 @@ IPRewriter::configure(Vector &conf, ErrorHandler *errh) return TCPRewriter::configure(conf, errh); } -inline IPRewriterEntry * +IPRewriterEntry * IPRewriter::get_entry(int ip_p, const IPFlowID &flowid, int input) { if (ip_p == IP_PROTO_TCP) @@ -189,6 +189,18 @@ IPRewriter::add_handlers() add_rewriter_handlers(true); } +void +IPRewriter::destroy_flow(IPRewriterFlow *flow) +{ + if (flow->ip_p() == IP_PROTO_TCP) + TCPRewriter::destroy_flow(flow); + else { + unmap_flow(flow, _udp_map, &reply_udp_map(flow->owner())); + flow->~IPRewriterFlow(); + _udp_allocator.deallocate(flow); + } +} + CLICK_ENDDECLS ELEMENT_REQUIRES(TCPRewriter UDPRewriter) EXPORT_ELEMENT(IPRewriter) diff --git a/elements/tcpudp/iprewriter.hh b/elements/tcpudp/iprewriter.hh index 50fb7423c1..698f627745 100644 --- a/elements/tcpudp/iprewriter.hh +++ b/elements/tcpudp/iprewriter.hh @@ -274,17 +274,7 @@ class IPRewriter : public TCPRewriter { public: }; -inline void -IPRewriter::destroy_flow(IPRewriterFlow *flow) -{ - if (flow->ip_p() == IP_PROTO_TCP) - TCPRewriter::destroy_flow(flow); - else { - unmap_flow(flow, _udp_map, &reply_udp_map(flow->owner())); - flow->~IPRewriterFlow(); - _udp_allocator.deallocate(flow); - } -} + CLICK_ENDDECLS #endif diff --git a/elements/tcpudp/tcprewriter.cc b/elements/tcpudp/tcprewriter.cc index 6e10003f7e..ca62a684d6 100644 --- a/elements/tcpudp/tcprewriter.cc +++ b/elements/tcpudp/tcprewriter.cc @@ -399,6 +399,14 @@ TCPRewriter::add_handlers() add_rewriter_handlers(true); } +void +TCPRewriter::destroy_flow(IPRewriterFlow *flow) +{ + unmap_flow(flow, _map); + static_cast(flow)->~TCPFlow(); + _allocator.deallocate(flow); +} + CLICK_ENDDECLS ELEMENT_REQUIRES(IPRewriterBase) EXPORT_ELEMENT(TCPRewriter) diff --git a/elements/tcpudp/tcprewriter.hh b/elements/tcpudp/tcprewriter.hh index bcae3fc57c..af694b27c2 100644 --- a/elements/tcpudp/tcprewriter.hh +++ b/elements/tcpudp/tcprewriter.hh @@ -194,13 +194,7 @@ class TCPRewriter : public IPRewriterBase { public: }; -inline void -TCPRewriter::destroy_flow(IPRewriterFlow *flow) -{ - unmap_flow(flow, _map); - static_cast(flow)->~TCPFlow(); - _allocator.deallocate(flow); -} + inline tcp_seq_t TCPRewriter::TCPFlow::new_seq(bool direction, tcp_seq_t seqno) const diff --git a/elements/tcpudp/udprewriter.cc b/elements/tcpudp/udprewriter.cc index b3d0f623ad..11a58d13b9 100644 --- a/elements/tcpudp/udprewriter.cc +++ b/elements/tcpudp/udprewriter.cc @@ -198,6 +198,14 @@ UDPRewriter::add_handlers() add_rewriter_handlers(true); } +void +UDPRewriter::destroy_flow(IPRewriterFlow *flow) +{ + unmap_flow(flow, _map); + flow->~IPRewriterFlow(); + _allocator.deallocate(flow); +} + CLICK_ENDDECLS ELEMENT_REQUIRES(IPRewriterBase) EXPORT_ELEMENT(UDPRewriter) diff --git a/elements/tcpudp/udprewriter.hh b/elements/tcpudp/udprewriter.hh index 42466243c5..17c235836d 100644 --- a/elements/tcpudp/udprewriter.hh +++ b/elements/tcpudp/udprewriter.hh @@ -218,13 +218,7 @@ class UDPRewriter : public IPRewriterBase { public: }; -inline void -UDPRewriter::destroy_flow(IPRewriterFlow *flow) -{ - unmap_flow(flow, _map); - flow->~IPRewriterFlow(); - _allocator.deallocate(flow); -} + CLICK_ENDDECLS #endif diff --git a/include/click/cxxprotect.h b/include/click/cxxprotect.h index 65662aff77..3a6528e809 100644 --- a/include/click/cxxprotect.h +++ b/include/click/cxxprotect.h @@ -4,7 +4,8 @@ # define delete linux_delete # define class linux_class # define virtual linux_virtual -# define typename linux_typename +// error: linux_typename does not name a type +//# define typename linux_typename # define protected linux_protected # define public linux_public # define namespace linux_namespace diff --git a/include/click/hashcode.hh b/include/click/hashcode.hh index 03d2f12996..6b88f4ac6f 100644 --- a/include/click/hashcode.hh +++ b/include/click/hashcode.hh @@ -2,6 +2,7 @@ #define CLICK_HASHCODE_HH CLICK_DECLS + // Notes about the hashcode template: On GCC 4.3.0, "template <>" is required // on the specializations or they aren't used. Just plain overloaded // functions aren't used. The specializations must be e.g. "const char &", @@ -20,70 +21,57 @@ inline hashcode_t hashcode(T const &x) { return x.hashcode(); } -template <> inline hashcode_t hashcode(char const &x) { return x; } -template <> inline hashcode_t hashcode(signed char const &x) { return x; } -template <> inline hashcode_t hashcode(unsigned char const &x) { return x; } -template <> inline hashcode_t hashcode(short const &x) { return x; } -template <> inline hashcode_t hashcode(unsigned short const &x) { return x; } -template <> inline hashcode_t hashcode(int const &x) { return x; } -template <> inline hashcode_t hashcode(unsigned const &x) { return x; } -template <> inline hashcode_t hashcode(long const &x) { return x; } -template <> inline hashcode_t hashcode(unsigned long const &x) { return x; } #if HAVE_LONG_LONG -template <> inline hashcode_t hashcode(long long const &x) { return (x >> 32) ^ x; } -template <> inline hashcode_t hashcode(unsigned long long const &x) { return (x >> 32) ^ x; } #endif #if HAVE_INT64_TYPES && !HAVE_INT64_IS_LONG && !HAVE_INT64_IS_LONG_LONG -template <> inline hashcode_t hashcode(int64_t const &x) { return (x >> 32) ^ x; } -template <> inline hashcode_t hashcode(uint64_t const &x) { return (x >> 32) ^ x; } diff --git a/include/click/string.hh b/include/click/string.hh index 969a82059a..7d1585601d 100644 --- a/include/click/string.hh +++ b/include/click/string.hh @@ -75,7 +75,7 @@ class String { public: static String make_numeric(uintmax_t x, int base = 10, bool uppercase = true); inline const char* data() const; - inline int length() const; + int length() const; inline const char *c_str() const; @@ -312,7 +312,7 @@ class StringRef { inline StringRef(const String &x); inline const char *data() const; - inline int length() const; + int length() const; inline const char *begin() const; inline const char *end() const; @@ -479,10 +479,7 @@ inline const char *String::data() const { return _r.data; } -/** @brief Return the string's length. */ -inline int String::length() const { - return _r.length; -} + /** @brief Null-terminate the string. @@ -869,9 +866,7 @@ inline const char *StringRef::data() const { return data_; } -inline int StringRef::length() const { - return len_; -} + inline const char *StringRef::begin() const { return data(); diff --git a/include/click/timestamp.hh b/include/click/timestamp.hh index 9b8e773dbc..028b9f03ce 100644 --- a/include/click/timestamp.hh +++ b/include/click/timestamp.hh @@ -230,7 +230,7 @@ class Timestamp { public: #endif } - inline seconds_type sec() const; + seconds_type sec() const; inline uint32_t subsec() const; inline uint32_t msec() const; inline uint32_t usec() const; @@ -1024,19 +1024,7 @@ Timestamp::set_subsec(uint32_t subsec) #endif } -/** @brief Return this timestamp's seconds component. */ -inline Timestamp::seconds_type -Timestamp::sec() const -{ -#if TIMESTAMP_REP_FLAT64 - if (unlikely(_t.x < 0)) - return -value_div(-(_t.x + 1), subsec_per_sec) - 1; - else - return value_div(_t.x, subsec_per_sec); -#else - return _t.sec; -#endif -} + /** @brief Return this timestamp's subseconds component. */ inline uint32_t diff --git a/lib/string.cc b/lib/string.cc index 15c845ee37..4a192be9de 100644 --- a/lib/string.cc +++ b/lib/string.cc @@ -1096,4 +1096,13 @@ String::skip_utf8_char(const unsigned char *first, const unsigned char *last) return first; } +/** @brief Return the string's length. */ +int String::length() const { + return _r.length; +} + +int StringRef::length() const { + return len_; +} + CLICK_ENDDECLS diff --git a/lib/timestamp.cc b/lib/timestamp.cc index 6c1033c72a..f8da3da717 100644 --- a/lib/timestamp.cc +++ b/lib/timestamp.cc @@ -259,4 +259,18 @@ Timestamp::unparse_interval() const return sa.take_string(); } +/** @brief Return this timestamp's seconds component. */ +Timestamp::seconds_type +Timestamp::sec() const +{ + #if TIMESTAMP_REP_FLAT64 + if (unlikely(_t.x < 0)) + return -value_div(-(_t.x + 1), subsec_per_sec) - 1; + else + return value_div(_t.x, subsec_per_sec); + #else + return _t.sec; + #endif +} + CLICK_ENDDECLS diff --git a/linuxmodule/click-linuxtool.pl b/linuxmodule/click-linuxtool.pl index dd4f8c7b85..a21bf51978 100755 --- a/linuxmodule/click-linuxtool.pl +++ b/linuxmodule/click-linuxtool.pl @@ -352,8 +352,32 @@ ($$) # de-const typeof in unions if ($d eq "compiler.h") { - s{(union\s*\{\s*typeof\()x\)}{$1x + 0)}g; - } + s{(union\s*\{\s*typeof\(x\).*__u);}{$1 = {0};}g; + } + + # BUILD_BUG_ON_* cannot define a struct inside sizeof(). + # Rather than negative-bitfield size, produce a negative array dimension. + if ($d eq "bug.h") { + s{(#define BUILD_BUG_ON_ZERO\(e\)) \(sizeof\(struct \{ int:-!!\(e\); \}\)\)}{$1 (sizeof(int[-!!(e)]))}g; + s{(#define BUILD_BUG_ON_NULL\(e\) \(\(void \*\))sizeof\(struct { int:-!!\(e\); }\)\)}{$1(sizeof(int[-!!(e)]))}g; + } + + if ($d eq "cxxprotect.h") { + s{(#\s+define\s+typename\s+linux_typename)}{# define typename typename}g; + } + + if ($d eq "syscall.h") { + s{(typedef\s+asmlinkage\s+long\s+\(\*sys_call_ptr_t\))}{asmlinkage typedef long (*sys_call_ptr_t)}g; + } + + if ($d eq "ip.h") { + s{(return\s+min\(READ_ONCE\(dst->dev->mtu\),\s+IP_MAX_MTU\))}{const typeof(dst->dev->mtu) a = READ_ONCE(dst->dev->mtu); + return min(a, IP_MAX_MTU)}g; + + s{return\s+min\(READ_ONCE\(skb_dst\(skb\)->dev->mtu\),\s+IP_MAX_MTU\)}{const typeof(skb_dst(skb)->dev->mtu) a = READ_ONCE(skb_dst(skb)->dev->mtu); + return min(a, IP_MAX_MTU)}g; + } + # fix illegal void* arithmetic s{(\w+)\s*-\s*\(\s*void\s*\*\s*\)}{(uintptr_t)$1 - (uintptr_t)}g; diff --git a/linuxmodule/proclikefs.c b/linuxmodule/proclikefs.c index 422659e62e..375cde0bdf 100644 --- a/linuxmodule/proclikefs.c +++ b/linuxmodule/proclikefs.c @@ -92,7 +92,9 @@ struct proclikefs_file_system { #define PROCLIKEFS_COUNT 2 static struct proclikefs_file_system fs_array[PROCLIKEFS_COUNT]; static struct mutex fslist_lock; -extern struct mutex inode_lock; +// error: ‘inode_lock’ redeclared as different kind of symbol +// inode_lock is never referenced. +// extern struct mutex inode_lock; #if !HAVE_LINUX_SB_LOCK # define lock_sb() @@ -298,7 +300,18 @@ proclikefs_unregister_filesystem(struct proclikefs_file_system *pfs) /* create a garbage inode (which requires creating a garbage superblock) */ inode_init_once(&dummy_inode); + + /* + timespec_trunc in kernel/time/time.c + if granularity is set to 0 it will produce a warning + if is set to one it will do nothing. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0) + dummy_sb.s_time_gran = 1; +#else dummy_sb.s_time_gran = 0; +#endif + dummy_inode.i_sb = &dummy_sb; make_bad_inode(&dummy_inode); if ((uintptr_t) &dummy_inode.i_fop->llseek