1#!/bin/bash 2 3# This file contains list-manipulation functions. 4 5# A list is defined here as a string of items separated by some delimiter. The PATH variable is one such 6# example. 7 8if ! test "${default_delim+defined}" ; then 9 readonly default_delim=" " 10fi 11 12# Performance note: It is important for these functions to run quickly. One way to increase their speed is 13# to avoid copying function arguments to local variables and to instead use numbered arguments (e.g. ${1}, 14# {2}, etc.) to access the arguments from inside the functions. In some trials, this doubled the speed of 15# the functions. The cost of this is that it makes the functions slightly more difficult to read. 16 17 18function add_list_element { 19 # local list_element="${1}" 20 # local list_name="${2}" 21 # local delim="${3:-${default_delim}}" 22 # local position="${4:-back}" 23 24 # Add the list_element to the list named in list_name. 25 26 # Description of argument(s): 27 # list_element The list element to be added. 28 # list_name The name of the list to be modified. 29 # delim The delimiter used to separate list elements. 30 # position Indicates the position in the list where the new element should be added 31 # ("front"/"back"). 32 33 if [ -z "${!2}" ] ; then 34 # The list is blank. Simply assign it the list_element value and return. 35 eval "${2}=\"${1}\"" 36 return 37 fi 38 39 if [ "${4:-back}" == "back" ] ; then 40 # Append the list_element to the back of the list and return. 41 eval "${2}=\"\${${2}}\${3-${default_delim}}\${1}\"" 42 return 43 fi 44 45 # Append the list_element to the front of the list and return. 46 eval "${2}=\"\${1}\${3-${default_delim}}\${${2}}\"" 47 48} 49 50 51function remove_list_element { 52 # local list_element="${1}" 53 # local list_name="${2}" 54 local delim="${3:-${default_delim}}" 55 56 # Remove all occurrences of list_element from the list named in list_name. 57 58 # Description of argument(s): 59 # list_element The list element to be removed. 60 # list_name The name of the list to be modified. 61 # delim The delimiter used to separate list elements. 62 63 local __rle_new_list__="${!2}" 64 65 # Special case: The list contains one element which matches the specified list element: 66 if [ "${1}" == "${__rle_new_list__}" ] ; then 67 eval ${2}=\"\" 68 return 69 fi 70 71 # Replace all occurrences of list_element that are bounded by the delimiter on both sides. 72 __rle_new_list__="${__rle_new_list__//${delim}${1}${delim}/${delim}}" 73 # Replace list_item if it occurs at the beginning of the string and is bounded on the right by the 74 # delimiter. 75 __rle_new_list__="${__rle_new_list__#${1}${delim}}" 76 # Replace list_item if it occurs at the end of the string and is bounded on the left by the delimiter. 77 __rle_new_list__="${__rle_new_list__%${delim}${1}}" 78 79 # Set caller's variable to new value. 80 eval ${2}=\"\${__rle_new_list__}\" 81 82} 83 84 85function cleanup_path_slashes { 86 local var_name="${1}" ; shift 87 88 # For the variable named in var_name, replace all multiple-slashes with single slashes and strip any 89 # trailing slash. 90 91 # Description of argument(s): 92 # var_name The name of the variable whose contents are to be changed. 93 94 local cmd_buf 95 96 cmd_buf="${var_name}=\$(echo \"\${${var_name}}\" | sed -re 's#[/]+#/#g' -e 's#/\$##g')" 97 eval "${cmd_buf}" 98 99} 100 101 102function remove_path { 103 local dir_path="${1}" ; shift 104 local path_var="${1:-PATH}" ; shift 105 106 # Remove all occurrences of dir_path from the path variable named in path_var. 107 108 # Note that this function will remove extraneous slashes from the elements of path_var. 109 110 # Description of argument(s): 111 # dir_path The directory to be removed from the path variable. 112 # path_var The name of a variable containing directory paths separated by colons. 113 114 cleanup_path_slashes dir_path || return 1 115 cleanup_path_slashes ${path_var} || return 1 116 remove_list_element "${dir_path}" "${path_var}" : || return 1 117 118} 119