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