#! /bin/bash
#########################################################################
#									#
#	wutconv is automatically generated,				#
#		please do not modify!					#
#									#
#########################################################################

#########################################################################
#									#
# Author: Copyright (C) 2014-2017, 2019, 2021, 2023, 2024  Mark Grant	#
#	  Copyright (C) 2026  Mark GRant				#
#									#
# Released under the GPLv3 only.					#
# SPDX-License-Identifier: GPL-3.0-only					#
#									#
# Purpose:								#
# Converts one or more text files to windows or unix line endings, or,	#
# if no text files are specified on the command line, then stdin is 	#
# converted to stdout.							#
#                                                              		#
# Syntax:      See usage().						#
#									#
# Exit codes used:-							#
# Bash standard Exit Codes:	0 - success				#
#				1 - general failure			#
# User-defined exit code range is 64 - 113				#
#	C/C++ Semi-standard exit codes from sysexits.h range is 64 - 78	#
#		EX_USAGE	64	command line usage error	#
#		EX_DATAERR	65	data format error		#
#		EX_NOINPUT	66	cannot open input		#
#		EX_NOUSER	67	addressee unknown		#
#		EX_NOHOST	68	host name unknown		#
#		EX_UNAVAILABLE	69	service unavailable		#
#		EX_SOFTWARE	70	internal software error		#
#		EX_OSERR	71	system error (e.g., can't fork)	#
#		EX_OSFILE	72	critical OS file missing	#
#		EX_CANTCREAT	73	can't create (user) output file	#
#		EX_IOERR	74	input/output error		#
#		EX_TEMPFAIL	75	temp failure; user is invited	#
#					to retry			#
#		EX_PROTOCOL	76	remote error in protocol	#
#		EX_NOPERM	77	permission denied		#
#		EX_CONFIG	78	configuration error		#
#	User-defined (here) exit codes range 79 - 113:			#
#		None							#
#									#
# Further Info:								#
#									#
#########################################################################


##################
# Init variables #
##################
readonly version=1.2.2				# Script version
readonly packageversion=1.4.0		# Package version

unix=false
windows=false
verbosity=""


#############
# Functions #
#############

# -h --help output.
# No parameters
# No return value
usage()
{
cat << EOF
Usage is:-
$(basename "$0") {-u|-w} [-v] [TEXT_FILE_NAME ...]
$(basename "$0") {-h|-V}
Usage is:-
$(basename "$0") [OPTIONS] [TEXT_FILE_NAME ...]
	-h or --help Displays usage information
	-u or --unix Convert to Unix line endings
	-v or --verbose verbose output
	-V or --version Displays version information
	-w or --windows Convert to Windows line endings
	List of text file names. If blank, stdin and stdout are used.
EOF
}

# Standard function to emit messages depending on various parameters.
# Parameters -	$1 What:-	The message to emit.
#		$2 Where:-	stdout == 0
#				stderr == 1
# No return value.
output()
{
	if (( !$2 )); then
		if [[ $verbosity == "-v" ]]; then
			printf "%s\n" "$1"
		fi
	else
		printf "%s\n" "$1" 1>&2
	fi
}

# Standard function to tidy up and return exit code.
# Parameters - 	$1 is the exit code.
# No return value.
script_exit()
{
	exit "$1"
}

# Standard function to test command error and exit if non-zero.
# Parameters - 	$1 is the exit code, (normally $? from the preceeding command).
# No return value.
std_cmd_err_handler()
{
	if (( $1 )); then
		script_exit "$1"
	fi
}

# Standard trap exit function.
# No parameters.
# No return value.
# shellcheck disable=SC2317  # Do not warn about unreachable commands in trap
# functions, they are legitimate.
trap_exit()
{
	local -i exit_code=$?
	local msg

	msg="Script terminating with exit code $exit_code due to trap received."
	output "$msg" 1
	script_exit "$exit_code"
}

# Setup trap.
trap trap_exit SIGHUP SIGINT SIGQUIT SIGTERM

# Process command line arguments with GNU getopt.
# Parameters -	$1 is the command line.
# No return value.
proc_CL()
{
	local GETOPTTEMP
	local tmpGETOPTTEMP

	tmpGETOPTTEMP="getopt -o huvVw --long help,unix,verbose,version,windows"
	GETOPTTEMP=$($tmpGETOPTTEMP -n "$0" -- "$@")
	std_cmd_err_handler $?

	eval set -- "$GETOPTTEMP"
	std_cmd_err_handler $?

	while true; do
		case "$1" in
		-h|--help)
			usage
			shift
			script_exit 0
			;;
		-u|--unix)
			if $windows ; then
				output "Cannot specify options u AND w." 1
				script_exit 64
			fi
			unix=true
			shift
			;;
		-v|--verbose)	verbosity="-v"
			shift
			;;
		-V|--version)
			printf "Script version %s\n" $version
			printf "Package version %s\n" $packageversion
			shift
			script_exit 0
			;;
		-w|--windows)
			if $unix ; then
				output "Cannot specify options w AND u." 1
				script_exit 64
			fi
			windows=true
			shift
			;;
		--)	shift
			break
			;;
		*)	output "Internal error." 1
			script_exit 64
			;;
		esac
	done

	# Either u or w flag must be set.
	if ! $windows && ! $unix ; then
		output "Either -u or -w must be set." 1
		script_exit 64
	fi

	# u and w flag cannot both be set.
	if $windows && $unix ; then
		output "-u and -w cannot both be set." 1
		script_exit 64
	fi

	# Save any filenames
	non_opt_args=( "$@" )
}


########
# Main #
########

proc_CL "$@"

# If no cmd line filenames then use stdin and stdout.
if (( ! ${#non_opt_args[@]} )) ; then
	if $unix ; then	# Convert to Unix line endings.
		gawk '{if (substr($0,length,1)=="\r")
			sub(/\r$/, "");
			print;}'
	else	# Convert to Windows line endings.
		gawk '{if (substr($0,length,1)!="\r")
			sub(/$/, "\r");
			print;}'
	fi
	# And exit
	output "Script complete with exit code: 0" 0
	script_exit 0
fi

# Otherwise process cmd line filenames in sequence.
for arg in "${non_opt_args[@]}" ; do
	# Check file exists, is a regular file  and is readable and writeable
	if [[ ! -f $arg ]]; then
		output "File $arg does not exist or is not a regular file." 1
		script_exit 66
	fi
	if [[ ! -r $arg || ! -w $arg ]]; then
		output "File $arg does not have the correct permissions." 1
		script_exit 77
	fi

	if $unix ; then		# Convert to Unix
		gawk '{if (substr($0,length,1)=="\r")
			sub(/\r$/, "");
			print;}' "$arg" > "$arg".tmp \
			&& mv -f "$arg".tmp "$arg"
		status=$?
		msg="Converted file $arg to Unix format "
		msg+="complete with status "$status
		output "$msg" $status
		std_cmd_err_handler $status
	else	# Convert to Windows line endings.
		gawk '{if (substr($0,length,1)!="\r")
			sub(/$/, "\r");
			print;}' "$arg" > "$arg".tmp \
			&& mv -f "$arg".tmp "$arg"
		status=$?
		msg="Converted file $arg to Windows format "
		msg+="complete with status "$status
		output "$msg" $status
		std_cmd_err_handler $status
	fi
done

# And exit
output "Script complete with exit code: 0" 0
script_exit 0

