Home | History | Annotate | Line # | Download | only in lint2
      1 # $NetBSD: t_lint2.sh,v 1.13 2021/12/16 09:38:54 rillig Exp $
      2 #
      3 # Copyright (c) 2021 The NetBSD Foundation, Inc.
      4 # All rights reserved.
      5 #
      6 # Redistribution and use in source and binary forms, with or without
      7 # modification, are permitted provided that the following conditions
      8 # are met:
      9 # 1. Redistributions of source code must retain the above copyright
     10 #    notice, this list of conditions and the following disclaimer.
     11 # 2. Redistributions in binary form must reproduce the above copyright
     12 #    notice, this list of conditions and the following disclaimer in the
     13 #    documentation and/or other materials provided with the distribution.
     14 #
     15 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     16 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     17 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     18 # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     19 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25 # POSSIBILITY OF SUCH DAMAGE.
     26 #
     27 
     28 lint2=/usr/libexec/lint2
     29 
     30 std_head()
     31 {
     32 	atf_set 'require.progs' "$lint2"
     33 }
     34 
     35 std_body()
     36 {
     37 	# shellcheck disable=SC2155
     38 	local srcdir="$(atf_get_srcdir)"
     39 
     40 	# remove comments and whitespace from the .ln file
     41 	sed -e '/^#/d' -e '/^$/d' -e 's,#.*,,' -e 's,[[:space:]],,g' \
     42 	    < "$srcdir/$1.ln" \
     43 	    > "$1.ln"
     44 
     45 	atf_check -o "file:$srcdir/$1.exp" \
     46 	    "$lint2" -h -x "$1.ln"
     47 }
     48 
     49 std_emit_body()
     50 {
     51 	# shellcheck disable=SC2155
     52 	local srcdir="$(atf_get_srcdir)"
     53 
     54 	# remove comments and whitespace from the .ln files
     55 	sed -e '/^#/d' -e '/^$/d' -e 's,#.*,,' -e 's,[[:space:]],,g' \
     56 	    < "$srcdir/$1.ln" \
     57 	    > "$1.ln"
     58 	sed -e '/^#/d' -e '/^$/d' -e 's,#.*,,' -e 's,[[:space:]],,g' \
     59 	    < "$srcdir/$1.exp-ln" \
     60 	    > "$1.exp-ln"
     61 
     62 	atf_check \
     63 	    "$lint2" -h -x -C "$1" "$1.ln"
     64 
     65 	atf_check -o "file:$1.exp-ln" \
     66 	    cat "llib-l$1.ln"
     67 }
     68 
     69 emit_body()
     70 {
     71 	std_emit_body 'emit'
     72 }
     73 
     74 emit_lp64_body()
     75 {
     76 	std_emit_body 'emit_lp64'
     77 }
     78 
     79 # usage: test_error input message-regex [input-regex]
     80 test_error()
     81 {
     82 	printf '%s\n' \
     83 	    "$1"
     84 	printf '%s\n' \
     85 	    '0sinput.ln' \
     86 	    'Sinput.ln' \
     87 	    "$1" \
     88 	    > 'input.ln'
     89 
     90 	atf_check -s 'exit:1' \
     91 	    -e "match:error: input\\.ln:3: $2 \\(for '${3-$1}'\\)\$" \
     92 	    "$lint2" 'input.ln'
     93 }
     94 
     95 test_error_ignored()
     96 {
     97 	printf '%s\n' \
     98 	    "$1"
     99 	printf '%s\n' \
    100 	    '0sinput.ln' \
    101 	    'Sinput.ln' \
    102 	    "$1" \
    103 	    > 'input.ln'
    104 
    105 	atf_check -o 'ignore' \
    106 	    "$lint2" 'input.ln'
    107 }
    108 
    109 error_cases_head()
    110 {
    111 	std_head
    112 }
    113 error_cases_body()
    114 {
    115 	test_error ''			'missing record type'
    116 	test_error '123'		'missing record type'
    117 	test_error '0X'			'not a number: '
    118 	test_error '0d'			'not a number: '
    119 	test_error '0dXYZ'		'not a number: XYZ'
    120 	test_error '0d123'		'bad line number'
    121 	test_error '0d123.XYZ'		'not a number: XYZ'
    122 	test_error '0X0.0'		'bad record type X'
    123 
    124 	# function calls
    125 	test_error '0c0.0'		'not a number: '
    126 	test_error '0c0.0uu'		'used or discovered: u'
    127 	test_error '0c0.0du'		'used or discovered: u'
    128 	test_error '0c0.0ui'		'used or discovered: i'
    129 	test_error '0c0.0di'		'used or discovered: i'
    130 	test_error '0c0.0ud'		'used or discovered: d'
    131 	test_error '0c0.0dd'		'used or discovered: d'
    132 	# Unlike 'd' and 'u', the 'i' may be repeated.
    133 	test_error '0c0.0iiiiiii1n_'	'bad type: _ '
    134 	# Negative argument numbers like in 'z-1' are accepted but ignored.
    135 	test_error '0c0.0z-1d_'		'not a number: _'
    136 	# Argument 1 is both positive '1p' and negative '1n', which is
    137 	# impossible in practice.  It is not worth handling this though since
    138 	# only lint1 generates these .ln files.
    139 	test_error '0c0.0p1n1d_'	'not a number: _'
    140 	test_error '0c0.0s'		'not a number: '
    141 	test_error '0c0.0s2'		'not quote: '
    142 	test_error '0c0.0s2|'		'not quote: |'
    143 	test_error '0c0.0s2"'		'trailing data: '
    144 	test_error '0c0.0s2"%'		'missing closing quote'
    145 	# shellcheck disable=SC1003
    146 	test_error '0c0.0s2"\'		'missing after \\'	'0c0\.0s2"\\'
    147 	# shellcheck disable=SC1003
    148 	test_error '0c0.0s2"%\'		'missing after \\'	'0c0\.0s2"%\\'
    149 
    150 	# declarations and definitions
    151 	test_error '0d0'		'bad line number'
    152 	test_error '0d0.0'		'not a number: '
    153 	test_error '0d0.0dd'		'def'
    154 	test_error '0d0.0de'		'decl'
    155 	test_error '0d0.0ee'		'decl'
    156 	test_error '0d0.0ii'		'inline'
    157 	test_error '0d0.0oo'		'osdef'
    158 	test_error '0d0.0rr'		'r'
    159 	test_error '0d0.0ss'		'static'
    160 	test_error '0d0.0tt'		'tdef'
    161 	test_error '0d0.0uu'		'used'
    162 	test_error '0d0.0v1v1'		'v'
    163 	test_error '0d0.0P1P1'		'P'
    164 	test_error '0d0.0S1S1'		'S'
    165 	test_error '0d0.0v1P1S_'	'not a number: _'
    166 	test_error '0d0.0d3var_'	'bad type: _ '
    167 	test_error '0d0.0d3varPV_'	'trailing line: _'
    168 
    169 	# usage of a variable or a function
    170 	test_error '0u0.0'		'bad delim '
    171 	test_error '0u0.0_'		'bad delim _'
    172 	test_error '0u0.0x'		'not a number: '
    173 
    174 	# trailing garbage is not detected
    175 	test_error_ignored '0u0.0x3var_'
    176 }
    177 
    178 missing_newline_head()
    179 {
    180 	std_head
    181 }
    182 
    183 missing_newline_body()
    184 {
    185 	# Before read.c 1.72 from 2021-12-16, the error message was just 'c'
    186 	# without any textual description or context, and the line number was
    187 	# off by one, it was reported as line 0.
    188 
    189 	printf '1d1.1e5func' > 'input.ln'
    190 
    191 	atf_check -s 'exit:1' \
    192 	    -e 'match:^.*: error: input\.ln:1: missing newline after .c. \(for .1d1\.1e5func.\)$' \
    193 	    "$lint2" 'input.ln'
    194 }
    195 
    196 atf_init_test_cases()
    197 {
    198 	local i
    199 
    200 	# shellcheck disable=SC2013
    201 	# shellcheck disable=SC2035
    202 	for i in $(cd "$(atf_get_srcdir)" && echo *.ln); do
    203 		i=${i%.ln}
    204 
    205 		case "$i" in
    206 		*lp64*)
    207 			case "$(uname -p)" in
    208 			*64) ;;
    209 			*) continue
    210 			esac
    211 		esac
    212 
    213 		type "${i}_head" 1>/dev/null 2>&1 \
    214 		|| eval "${i}_head() { std_head; }"
    215 		type "${i}_body" 1>/dev/null 2>&1 \
    216 		|| eval "${i}_body() { std_body '$i'; }"
    217 		atf_add_test_case "$i"
    218 	done
    219 
    220 	atf_add_test_case 'error_cases'
    221 	atf_add_test_case 'missing_newline'
    222 }
    223