#!/bin/bash
# core/lib - Loadable library support
#
# The ``lib`` library provides  the foundation for dynamic library
# loading in the MCSH framework.

set -e


######
# library interface

core_lib_config_init() {
	#; Documented in the runtime library
	lib_setting_vars lib_debug

	#; Documented in the runtime library
	lib_setting_arrays lib_name

	# $lib_loaded[] - Lists libraries in the order they were loaded
	# $lib_inited[] - Lists libraries in the order they were initialized
	lib_setting_arrays lib_loaded lib_inited
}


######
# Internal Functions

# lib_load_check() - Check library loads, temporarily alterning
# logging messages to improve debugging.  This definition replaces the
# basic implementation provided by the main runtime library (`mcsh`).
lib_load_check() {
	local name="$lib_name"
	local -a script=( "${lib_name[@]}" )
	list_reverse script

	# check for built-in library
	if in_list "$name" "${package_libs[@]}"; then
		lib_debug "$name: loading library"
	else
		lib_info "$name: loading user library"
	fi

	local file
	file=$(lib_filename "$name")
	[ -f "$file" ] || error "$file: library not found"
}

######
# Library Command Dispatch

# lib_load_dispatch() - Loads library ($1) and runs command in namespace ($2)
lib_load_dispatch_ns() {
	local name=$1
	local namespace=$2
	shift 2

	lib_load "$name"
	lib_cmd_dispatch "$namespace" "$@"
}

# lib_load_dispatch_ns() - Loads the named library ($1) and runs the command in default namespace
lib_load_dispatch() {
	lib_load_dispatch_ns "$1" "${1#*/}" "$@"
}


######
# Library Configuration Settings

# The functions provided in this section should only be used inside
# the ``config_init`` callback of libraries to define their settings.
# For more information, see the `core/settings` library.

# lib_setting_vars() - Adds variable settings for the current library.
lib_setting_vars() { settings_add_vars "$(lib_symbol $lib_name)" "$@"; }

# lib_setting_arrays() - Adds array settings for the current library.
lib_setting_arrays() { settings_add_arrays "$(lib_symbol $lib_name)" "$@"; }

# lib_setting_assocs() - Adds associative arrays for the current library.
lib_setting_assocs() { settings_add_assocs "$(lib_symbol $lib_name)" "$@"; }

# lib_setting_funcs() - Adds function settings for the current library.
lib_setting_funcs() { settings_add_funcs "$(lib_symbol $lib_name)" "$@"; }


######
# Library Command Dispatch

# lib_cmd_name() - Prints a library command name for the given commands ($@)
lib_cmd_name() {
	local -a a=( "${lib_name[@]}" "$@" )
	list_map lib_symbol a
	echo "$(IFS="_"; echo "${a[*]}")"
}

# lib_cmd_exists() - Returns true if a library ($1) contains a function to
# handle the given commands ($@).
lib_cmd_exists() {
	min_args 2 "$@"
	local name=$1
	shift

	local -a lib_name=( "$name" )
	is_function $(lib_cmd_name "$@")
}

# lib_cmd_exec() - Runs a command ($2) in a library ($1), if it exists.
# $1 - Library name
# $2 - Command name
# $@ - Extra arguments
lib_cmd_exec() {
	min_args 2 "$@"
	local name=$1
	local cmd=$2
	shift 2

	if lib_cmd_exists "$name" "$cmd"; then
		local -a lib_name=( "$name" )
		$(lib_cmd_name $cmd) "$@"
	fi
}

# lib_cmd_dispatch() - Dispatches commands in the given library namespace ($1).
lib_cmd_dispatch() {
	min_args 1 "$@"
	local name=$1
	shift
	local -a script=( $name )
	cmd_dispatch "$@"
}


######
# Library Iteration

# for_each_lib() - Calls the given command ($@) for each initialized library.
for_each_lib() { for_each "$*" "${lib_inited[@]}"; }

# for_each_lib_loaded() - Calls the given command ($@) for each loaded library.
for_each_lib_loaded() { for_each "$*" "${lib_loaded[@]}"; }


######
# Library Dependencies

# lib_dep_list() - Prints list of library dependencies for the given
# library script file ($1)
lib_dep_list() {
	local file=$1
	grep -Pe '^[#\t ]*lib_load ' "$file" \
		| sed -e "s,^lib_load ['\"]*,!," \
			-e "s,^.*lib_load ['\"]*,," \
			-e "s,['\"] *$,,"
}

# lib_deps() - Prints list of dependencies for the given library ($1)
lib_deps() {
	local name=$1
	local file
	file=$(lib_filename "$name")
	lib_dep_list "$file"
}


######
# Library Testing

# lib_check() - Runs the ``check`` method for the named library ($1)
lib_check() {
	local name=$1
	if is_function "$(lib_symbol $name)_lib_check"; then
		app_echo "$name: checking library..."
		lib_cmd_exec "$1" lib_check
	fi
}

# lib_check_all() - Runs the ``check`` method for all libraries
lib_check_all() {
	app_echo "checking libraries..."
	for_each_lib lib_check
	app_echo "... done checking libraries"
}

View the Developer Guide Index

View the Reference Manual Index


Generated on Fri Jul 28 14:34:58 PDT 2017 by mcsh d14 v0.23.0.