#! /bin/sh
# $NetBSD: t_misc.sh,v 1.29 2023/12/17 10:02:09 rillig Exp $
#
# Copyright (c) 2021 The NetBSD Foundation, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# Tests for indent that do not follow the input-profile-output scheme that is
# used in t_options.
atf_test_case 'in_place_parse_error'
in_place_parse_error_body()
{
# On normal parse errors, indent continues until the end of the file.
# This means that even in the case of errors, not much is lost.
# The code in args.c function load_profile suggests that options from
# profile files are echoed to stderr during startup. But since the
# command line options are handled after the profile files, a '-v' in
# the command line has no effect. That's why '-bacc' is not listed
# on stderr, but '-fc1' is. The second round of '-bacc', '-v', '-fc1'
# is listed because when running the test via ATF, $HOME equals $PWD.
atf_test_case 'option_P_in_profile_file'
option_P_in_profile_file_body()
{
# Mentioning another profile via -P has no effect since only a single
# profile can be specified on the command line, and there is no
# 'include' option.
# It's syntactically possible to specify a profile file inside another
# profile file. Such a profile file is ignored since only a single
# profile file is ever loaded.
printf '%s\n' '-P/nonexistent' > .indent.pro
atf_test_case 'option_without_hyphen'
option_without_hyphen_body()
{
# Ensure that options in profile files start with '-', just like
# command line options.
printf ' -i3 xi5 +di0\n' > .indent.pro
printf '%s\n' 'int var[] = {' '1,' '}' > code.c
atf_check \
-s 'exit:1' \
-e "match:/.indent.pro: option \"xi5\" must start with '-'" \
"$indent" < code.c
}
atf_test_case 'opt'
opt_body()
{
# Test parsing of command line options from a profile file.
cat <<-\EOF > code.c
int global_var;
int function(int expr) {
switch (expr) { case 1: return 1; default: return 0; }
}
EOF
cat << \EOF > .indent.pro
/* The latter of the two options wins. */
-di5
-di12
/*
* It is possible to embed comments in the middle of an option, but nobody
* does that.
*/
-/* comment */bacc
-T/* define
a type */custom_type
/* For int options, trailing garbage would be an error. */
-i3
/* For float options, trailing garbage would be an error. */
-cli3.5
-b/*/acc /* The comment is '/' '*' '/', making the option '-bacc'. */
EOF
sed '/[$]/d' << \EOF > code.exp
/* $ The variable name is indented by 12 characters due to -di12. */
int global_var;
int
function(int expr)
{
switch (expr) {
/* $ The indentation is 3 + (int)(3.5 * 3), so 3 + 10.5, so 13. */
/* $ See parse.c, function parse, 'case switch_expr'. */
case 1:
/* $ The indentation is 3 + (int)3.5 * 3 + 3, so 3 + 9 + 3, so 15. */
/* $ See parse.c, function parse, 'case switch_expr'. */
return 1;
default:
return 0;
}
}
EOF
atf_test_case 'opt_npro'
opt_npro_body()
{
# Mentioning the option -npro in a .pro file has no effect since at
# that point, indent has already decided to load the .pro file, and
# it only decides once.
atf_test_case 'opt_U'
opt_U_body()
{
# From each line of this file, the first word is taken to be a type
# name.
#
# Since neither '/*' nor '' are syntactically valid type names, this
# means that all kinds of comments are effectively ignored. When a
# type name is indented by whitespace, it is ignored as well.
#
# Since only the first word of each line is relevant, any remaining
# words can be used for comments.
cat <<-\EOF > code.types
/* Comments are effectively ignored since they never match. */
# This comment is ignored as well.
; So is this comment.
# The following line is empty and adds a type whose name is empty.
size_t from stddef.h
off_t for file offsets
ignored_t is ignored since it is indented
EOF
cat <<-\EOF > code.c
int known_1 = (size_t) * arg;
int known_2 = (off_t) * arg;
int ignored = (ignored_t) * arg;
EOF
cat <<-\EOF > code.exp
int known_1 = (size_t)*arg;
int known_2 = (off_t)*arg;
int ignored = (ignored_t) * arg;
EOF
atf_test_case 'line_no_counting'
line_no_counting_body()
{
# Before NetBSD indent.c 1.147 from 2021-10-24, indent reported the
# warning in line 2 instead of the correct line 3.
atf_test_case 'several_profiles'
several_profiles_body()
{
# If the option '-P' occurs several times, only the last of the
# profiles is loaded, the others are ignored.
atf_test_case 'command_line_vs_profile'
command_line_vs_profile_body()
{
# Options from the command line override those from a profile file,
# no matter if they appear earlier or later than the '-P' in the
# command line.