[v2,2/5] color: add colors to zone and ports

Message ID 1497543533-5925-2-git-send-email-jonatan.schlag@ipfire.org
State Superseded
Headers show

Message

Jonatan Schlag June 15, 2017, 4:18 p.m.
Signed-off-by: Jonatan Schlag <jonatan.schlag@ipfire.org>
---
 src/functions/functions.colors | 192 +++++++++++++++++++++++++++++++++++++++++
 src/functions/functions.ports  |   8 ++
 src/functions/functions.zone   |   8 ++
 3 files changed, 208 insertions(+)

Comments

Michael Tremer June 19, 2017, 11:19 a.m. | #1
Hi,

there is a problem with the color_cli() function:

On Thu, 2017-06-15 at 18:18 +0200, Jonatan Schlag wrote:
> Signed-off-by: Jonatan Schlag <jonatan.schlag@ipfire.org>
> ---
>  src/functions/functions.colors | 192
> +++++++++++++++++++++++++++++++++++++++++
>  src/functions/functions.ports  |   8 ++
>  src/functions/functions.zone   |   8 ++
>  3 files changed, 208 insertions(+)
> 
> diff --git a/src/functions/functions.colors b/src/functions/functions.colors
> index 8d7193c..433ce78 100644
> --- a/src/functions/functions.colors
> +++ b/src/functions/functions.colors
> @@ -73,3 +73,195 @@ MSG_STP_DISCARDING="${CLR_RED_BG}${CLR_WHITE_B} DISCARDING
> ${CLR_RESET}"
>  MSG_STP_LEARNING="${CLR_YELLOW_BG}${CLR_WHITE_B}  LEARNING   ${CLR_RESET}"
>  MSG_STP_LISTENING="${CLR_YELLOW_BG}${CLR_WHITE_B}  LISTENING  ${CLR_RESET}"
>  MSG_STP_BLOCKING="${CLR_RED_BG}${CLR_WHITE_B}  BLOCKING   ${CLR_RESET}"
> +
> +color_cli() {
> +	#Is the cli function to parse the options submitted by a user.
> +	local type=${1}
> +	local name=${2}
> +	local action=${3}
> +	shift 3

Here you shift the arguments...

> +
> +	case ${action} in
> +		set)
> +			local color=${4}

And here you access the fourth one which has been shifted to ${1} by calling
shift 3 earlier.

So either drop the shift (preferred), or change the argument to ${1} here.

> +			# Check if we get to many arguments
> +			shift 1

This is shift is also unnecessary. You could just check for > 1 below.

> +			if [ $# -gt 0 ]; then
> +				error "Too many arguments: $@"
> +				return ${EXIT_ERROR}
> +			fi
> +			color_set ${type} ${name} ${@}
> +			;;
> +		reset)
> +			# We set the color to white.
> +			# Check if we get to many arguments
> +			shift
> +			if [ $# -gt 0 ]; then

Same as above.

> +				error "Too many arguments: $@"
> +				return ${EXIT_ERROR}
> +			fi
> +			color_set ${type} ${name} "ffffff"
> +			;;
> +		*)
> +			error "Invalid argument: ${action}"
> +			;;
> +	esac
> +
> +}
> +
> +color_set() {
> +	#Write a given color into the color config file of a zone or port.
> +	assert [ $# -eq 3 ]
> +
> +	local type=${1}
> +	local name=${2}
> +	local COLOR=${3}
> +	# Check if we get to many arguments
> +	# Check if the color code is valid
> +	if ! color_hex_is_valid ${COLOR}; then
> +		error "Hexadecimal color code '${COLOR}' is not valid"
> +		return ${EXIT_ERROR}
> +	fi
> +
> +	local file=$(color_format_filename ${type} ${name})
> +	settings_write ${file} COLOR
> +}
> +
> +color_read() {
> +	#Read a color out of color config file of a zone or port.
> +	#If this is unsuccessful we use white.
> +	local type=${1}
> +	local name=${2}
> +
> +	local file=$(color_format_filename ${type} ${name})
> +
> +	local COLOR
> +
> +	if ! settings_read ${file} COLOR; then
> +		COLOR="ffffff"
> +	fi
> +
> +	print "${COLOR}"
> +}
> +
> +color_format_filename() {
> +	#Formats the color config file name.
> +	local type=${1}
> +	local name=${2}
> +	case ${type} in
> +		zone)
> +			echo "$(zone_dir ${name})/color"
> +			;;
> +		port)
> +			echo "$(port_dir ${name})/color"
> +			;;
> +	esac
> +}
> +
> +color_hex_is_valid() {
> +	#Check if a color hex is valid.
> +	[[ ${1} =~ ^[0-9a-fA-F]{6}$ ]]
> +}
> +
> +color_hex2rgb() {
> +	#Converts a color hex into rgb values.
> +	local hex=${1}
> +
> +	assert [ ${#hex} -eq 6 ]
> +
> +	for (( i = 0; i < 6; i += 2 )); do
> +		hex2dec ${hex:${i}:2}
> +	done | tr '\n' ' '
> +
> +	print # newline
> +}
> +
> +_find_nearest_rgb_value() {
> +	# For the calculation of the xterm value the rgb values must be:
> +	# 0; 95; 135; 175; 215; 255;
> +	# this function find the closest value of these 6 numbers for a give
> rgb number
> +	local rgb=${1}
> +
> +	local best_value
> +	local best_value_index
> +
> +	local values=( 0 95 135 175 215 255 )
> +	local result
> +	local i=0
> +
> +	local value
> +	for value in ${values[@]}; do
> +		result=$(( ${value} - ${rgb} ))
> +		result=$(abs ${result})
> +
> +		if [ -z ${best_value} ]; then
> +			best_value=${result}
> +			best_value_index=${i}
> +
> +		# In the first iteration best_value is empty and so set to
> ${result}
> +		# two lines above. So if statement must use -le because in
> the first iteration
> +		# is the best_value eqal to result
> +		elif [ ${result} -le ${best_value} ]; then
> +			best_value=${result}
> +			best_value_index=${i}
> +		fi
> +
> +		(( i++ ))
> +	done
> +
> +	echo "${best_value_index}"
> +}
> +
> +color_rgb2shell() {
> +	#Converts a rgb value triple into an xterm color code.
> +	assert [ $# -eq 3 ]
> +
> +	local red=${1}
> +	local green=${2}
> +	local blue=${3}
> +
> +	local color
> +	for color in red green blue; do
> +		printf -v "${color}" $(_find_nearest_rgb_value ${!color})
> +	done
> +
> +	print $(( 16 + 36 * ${red} + 6 * ${green} + ${blue} ))
> +}
> +
> +color_set_shell() {
> +	#Set the shell color which unfourtunately does not work for putty.
> +	local where=${1}
> +	local color=${2}
> +
> +	local prefix
> +	case "${where}" in
> +		fg)
> +			prefix="\e[38"
> +			;;
> +		bg)
> +			prefix="\e[48"
> +			;;
> +	esac
> +
> +	# Convert color from hex to RGB
> +	local red green blue
> +	read red green blue <<< $(color_hex2rgb ${color})
> +
> +	# Set standard shell color
> +	local shell_color=$(color_rgb2shell ${red} ${green} ${blue})
> +	printf "${prefix};5;${shell_color}m"
> +
> +	# For shells that support it, we will try to set the RGB color code
> +	case "${TERM}" in
> +		putty*)
> +			# PuTTY is a piece of garbage and does not know
> +			# how to handle colors at all although it has nice
> +			# checkboxes to enable them, but they actually make
> +			# things even worse. So no colors for you Windows
> +			# users.
> +			;;
> +		*)
> +			printf "${prefix};2;${red};${green};${blue}m"
> +			;;
> +	esac
> +}
> diff --git a/src/functions/functions.ports b/src/functions/functions.ports
> index c6e45d0..94fc68b 100644
> --- a/src/functions/functions.ports
> +++ b/src/functions/functions.ports
> @@ -422,3 +422,11 @@ ports_lowest_address() {
>  port_identify() {
>  	device_identify $@
>  }
> +
> +port_get_color() {
> +	# This function return the color of a port
> +	assert [ $# -eq 1 ]
> +
> +	local name=${1}
> +	echo $(color_read "port" ${name})

You could just call "color_read port ${name}" here without the echo and the
$(...) since color_read already prints the result. This would save us calling a
subshell and would also make port_get_color return the exit code of color_read.

> +}
> diff --git a/src/functions/functions.zone b/src/functions/functions.zone
> index 88c81a8..68d4ab6 100644
> --- a/src/functions/functions.zone
> +++ b/src/functions/functions.zone
> @@ -1200,3 +1200,11 @@ zone_port_settings_remove() {
>  	local path="$(zone_dir "${zone}")/ports/${port}"
>  	settings_remove "${path}"
>  }
> +
> +zone_get_color() {
> +	# This function return the color of a zone
> +	assert [ $# -eq 1 ]
> +
> +	local name=${1}
> +	echo $(color_read "zone" ${name})
> +}

Likewise.