#!/bin/sh
#$Id: get_version,v 1.12 2022/12/13 20:00:22 marcum Exp $

# ==============================================================================
# Output version number for SimSys source, library or executable code.
#
# get_version [-sbin,-doc,-exe,-interface,-lib,-src,-include]
# 		[-build] [-o] [name(s)]
# 
# Get version number from version file (sbin, doc, interface or source), object
# library or executable.
# 
# -build	: Get build number instead of version number if available.
# 		  Build numbers differ only with executable files.
# 
# -o		: List version file directory, version file and version_number.
# 		  Only applicable with -sbin, -doc, -interface, -prog,
# 		  or -src options.
# 
# -sbin		: Get version number of sbin directory and ignore list of names,
# 		  "name(s)".
# 
# -doc		: Get version number of document directory for names, "names".
# 
# -exe		: Get version number of executable for names, "names".
# 
# -interface	: Get version number of interface directory for names, "names".
# 
# -lib		: Get version number of object library for names, "names".
# 
# -prog		: Get version number of main program for names, "names".
# 
# -src		: Get version number of source directory for names, "names".
# 		  This is the default.
# 
# -include	: Get version number of include directory for names, "names".
# 
# name(s)	: List of source, object library or executable names.
# ==============================================================================

# ==============================================================================
# Function to get build number from program output
# ==============================================================================

set_build_number ()
{
	set -- ${output}

	if [ "$#" = "0" ]; then

		version_number=

	elif [ "$#" = "1" ]; then

		version_number=$1

	elif [ "`expr $# \>\= 3`" = "1" ] && [ "`echo $* | grep -i \"Build Number\"`" != "" ]; then

		version_number=

		while [ X"$1" != X-- ]; do

			case "$1"
			in  
				"")		set -- -- $@
						;;

				Build)		if [ "`expr $# \>\= 3`" = "1" ] && [ "$2" = "Number" ]; then
							version_number=$3
							set -- -- $@
						else
							shift 2
						fi
						;;

				*)		shift 1
						;;
			esac
		done
	fi
}

# ==============================================================================
# Function to get build number from program output
# ==============================================================================

set_version_number ()
{
	set -- ${output}

	if [ "$#" = "0" ]; then

		version_number=

	elif [ "$#" = "1" ]; then

		version_number=$1

	elif [ "`expr $# \>\= 3`" = "1" ] && [ "`echo $* | grep -i \"Version Number\"`" != "" ]; then

		version_number=

		while [ X"$1" != X-- ]; do

			case "$1"
			in  
				"")		set -- -- $@
						;;

				Version)	if [ "`expr $# \>\= 3`" = "1" ] && [ "$2" = "Number" ]; then
							version_number=$3
							set -- -- $@
						else
							shift 2
						fi
						;;

				*)		shift 1
						;;
			esac
		done
	fi
}

# ==============================================================================
# Function to get version number
# ==============================================================================

get_version ()
{
# -----------------------------------------
# Set current architecture types
# -----------------------------------------

	set_current_arch_type

	if [ "${def_arch_type}" = "${arch_type_32}" ]; then

		arch_type2="${arch_type_64}"
	else
		arch_type2="${arch_type_32}"
	fi

# -----------------------------------------
# Get options
# -----------------------------------------

	build_number_flag=
	list_src_dir=
	names=
	type=src

	while [ X"$1" != X-- ]; do

		case "$1"
		in  
			"")		set -- -- $@
					;;

			-build)		build_number_flag=yes
					shift 1
					;;

			-o)		list_src_dir=yes
					shift 1
					;;

			-sbin)		type=sbin
					shift 1
					;;

			-doc)		type=doc
					shift 1
					;;

			-exe)		type=exe
					shift 1
					;;

			-interface)	type=interface
					shift 1
					;;

			-lib)		type=lib
					shift 1
					;;

			-prog)		type=prog
					shift 1
					;;

			-src|-include)	type=src
					shift 1
					;;

			-*)		exit
					;;

			*)		names="${names} $1"
					shift 1
					;;
		esac
	done

# -----------------------------------------
# Set list of code names
# -----------------------------------------

	if [ "${type}" = "sbin" ]; then

		names=${type}
	fi

	if [ "${names}" = "" ]; then

		exit
	fi

	set -- ${names}

	number_of_names=$#

	names="$*"

# -----------------------------------------
# Get version numbers for executables
# -----------------------------------------

	if [ "${type}" = "exe" ]; then

		for name in ${names}; do

			version_number=

			run_command_list="\
${sys_dir}/${arch_type}/bin/${name} \
${sys_dir}/${arch_type}/bin/${name}.exe \
${sys_dir}/${arch_type2}/bin/${name} \
${sys_dir}/${arch_type2}/bin/${name}.exe \
"

			if [ "${build_number_flag}" = "yes" ]; then

				run_option_list="-build -version --build"

				for run_command in ${run_command_list}; do

					for run_option in ${run_option_list}; do

						if [ "${version_number}" = "" ]; then

							output="`${run_command} ${run_option} 2> /dev/null`"

							set_build_number
						fi
					done
				done
			fi

			if [ "${version_number}" = "" ]; then

				run_option_list="-ver -version --version"

				for run_command in ${run_command_list}; do

					for run_option in ${run_option_list}; do

						if [ "${version_number}" = "" ]; then

							output="`${run_command} ${run_option} 2> /dev/null`"

							set_version_number
						fi
					done
				done
			fi

			if [ "${number_of_names}" = "1" ]; then

				echo "${version_number}"
			else
				echo "${name} ${version_number}"
			fi
		done

# -----------------------------------------
# Get version numbers for libraries
# -----------------------------------------

elif [ "${type}" = "lib" ]; then

		for name in ${names}; do

			version_number="`${sys_dir}/${arch_type}/bin/chklibv.exe ${name}`"

			if [ ! "${version_number}" ] && [ -e ${sys_dir}/src/${name}/${name}_version ]; then
				version_number="`cat ${sys_dir}/src/${name}/${name}_version`"
			fi

			if [ "${number_of_names}" = "1" ]; then

				echo "${version_number}"
			else
				echo "${name} ${version_number}"
			fi
		done

# --------------------------------------------------------------------
# Get version numbers for source, program, script or doc files 
# --------------------------------------------------------------------

	else
		if [ "${type}" = "prog" ]; then

			sys_src_dir=${sys_dir}/src

		elif [ "${type}" = "sbin" ]; then

			sys_src_dir=${sys_dir}
		else
			sys_src_dir=${sys_dir}/${type}
		fi

		if [ ! -d ${sys_src_dir} ]; then

			echo "*** unable to find system source directory ${sys_src_dir} ***"
			exit
		fi

		ifs_def="${IFS}"

		for name in ${names}; do

			src_dir=${sys_src_dir}/${name}

			if [ "${type}" = "prog" ]; then

				src_dir=${src_dir}/main
			fi

			if [ ! -d ${src_dir} ]; then

				exit
			fi

			cd ${src_dir}

# -----------------------------------------
# Get version numbers for source files
# -----------------------------------------

			if [ "${type}" = "src" ]; then

				file_name=

				file_name_list="${name}_version.cpp ${name}_version.cxx ${name}_version.c ${name}_version.f ${name}_version"

				for check_file_name in ${file_name_list}; do

					if [ -r "${check_file_name}" ]; then

						file_name="${check_file_name}"

						break
					fi
				done

# ------------------------------------------
# Get version numbers for main program files
# ------------------------------------------

			elif [ "${type}" = "prog" ]; then

				file_name=

				file_name_list="*.c ../main/*.c"

				for check_file_name in ${file_name_list}; do

					if [ -r "${check_file_name}" ] && [ "echo ${check_file_name}" != "${name}_version.cpp" ] && [ "echo ${check_file_name}" != "${name}_version.c" ] && [ "echo ${check_file_name}" != "${name}_version.f" ]; then

						if [ "`grep void\ main ${check_file_name}`" != "" ] || [ "`grep int\ main ${check_file_name}`" != "" ]; then
							if [ "`grep Version_Number ${check_file_name}`" != "" ]; then

								file_name="${check_file_name}"

								break
							fi
						fi
					fi
				done

# ---------------------------------------------------
# Get version numbers for script or doc files 
# ---------------------------------------------------

			else
				file_name=${name}_version

				if [ ! -r "${file_name}" ]; then

					check_file_name=${file_name}

					file_name=

					dir_name_list="*/"

					for dir_name in ${dir_name_list}; do

						if [ -r "${dir_name}/${check_file_name}" ]; then

							file_name=${check_file_name}

							cd ${dir_name}

							src_dir="`pwd`"

							break
						fi
					done
				fi
			fi

# ----------------------------------------------------
# Exit if no appropriate version file was found
# ----------------------------------------------------

			if [ "${file_name}" = "" ] || [ ! -r "${file_name}" ]; then

				exit
			fi

# ----------------------------------------------------
# Get version numbers for source or main program files 
# ----------------------------------------------------

			if [ "${type}" = "src" ] || [ "${type}" = "prog" ]; then

				version_line="`grep Version_Number ${file_name} | grep strncpy`"

				IFS="\""

				set -- ${version_line}

				version_number="$2"

				IFS="${ifs_def}"

				if [ ! "${version_number}" ]; then

					version_number="`cat ${file_name}`"
				fi
			else

				version_number="`cat ${file_name}`"
			fi

# ---------------------------------------------------
# Get version numbers for script or doc files 
# ---------------------------------------------------

			if [ "${list_src_dir}" = "yes" ]; then

				echo "${src_dir} ${file_name} ${version_number}"
			else

				if [ "${number_of_names}" = "1" ]; then

					echo "${version_number}"
				else
					echo "${name} ${version_number}"
				fi
			fi
		done
	fi
}
