# ============================================================================== # This file contains the following functions: # element_n # element_i # i_of_element # i_of_elempref # elem_of_elempref # element_assoc # element_from_to # ============================================================================== # ============================================================================== # $element_start: position on the element string of the start of the element(s) # $element_end: position on the element string of the end of the element(s) # ============================================================================== $element_start = -1 $element_end = -1 # ============================================================================== # element_n(array[, delim[, match_t]]): returns the number of elements in the # given string, using the given delimiter. # # Parameters: # $1 - the string containing all elements # $2 - the delimiter (defaults to "\n", used as "case"; if empty, # space delimiters will be used: ie "[ \t\r\n\v\f]*"/"regex") # $3 - match type for delimiter (default "case": see $2) # Returns: # The number of elements: this is at least 1 (no delimiter found), unless # the array string was empty to start with. # ============================================================================== define element_n { array = $1 if (length(array) == 0) return 0 delim = "\n" if ($n_args >= 2) delim = $2 match_t = "case" if ($n_args >= 3) match_t = $3 if (delim == "") { delim = "[ \t\r\n\v\f]*" match_t = "regex" } dd_beg = 0 dd_end = 0 count = 0 for (dd_beg = search_string(array, delim, dd_end, match_t), \ dd_end = $search_end; \ dd_beg != -1; \ dd_beg = search_string(array, delim, dd_end, match_t), \ dd_end = $search_end) { count++ } $element_start = 0 $element_end = length(array) return count + 1 } # ============================================================================== # element_i(array, index[, delim[, match_t]]): returns the element with the # given index, where elements are separated by the given delimiter in the # given string. It fails if the number of elements in the string is less # than or equal to the index (indexes start from zero). # # Parameters: # $1 - the string containing all elements # $2 - the index (must be a number) # $3 - the delimiter (defaults to "\n", used as "case"; if empty, # space delimiters will be used: ie "[ \t\r\n\v\f]*"/"regex") # $4 - match type for delimiter (default "case": see $3) # Returns: # The substring corresponding to the index, or the empty string on # failure. # ============================================================================== define element_i { array = $1 if (length(array) == 0) return "" index = $2 delim = "\n" if ($n_args >= 3) delim = $3 match_t = "case" if ($n_args >= 4) match_t = $4 if (delim == "") { delim = "[ \t\r\n\v\f]*" match_t = "regex" } ss_beg = 0 ss_end = 0 dd_beg = 0 dd_end = 0 found = 0 count = 0 if (index >= 0) { for (dd_beg = search_string(array, delim, dd_end, "regex"), \ dd_end = $search_end; \ count <= index; \ dd_beg = search_string(array, delim, dd_end, "regex"), \ dd_end = $search_end) { if (count == index) { if (dd_beg == -1) dd_beg = length(array) ss_end = dd_beg found = 1 break } else if (dd_beg == -1) break else { count++ ss_beg = dd_end } } } if (found) { $element_start = ss_beg $element_end = ss_end return substring(array, ss_beg, ss_end) } return "" } # ============================================================================== # i_of_element(array, elem[, delim[, match_t]]): returns the index of the given # element, or -1 on failure. The element must match exactly. # # Parameters: # $1 - the string containing all elements # $2 - the element to find # $3 - the delimiter (defaults to "\n", used as "case"; if empty, # space delimiters will be used: ie "[ \t\r\n\v\f]*"/"regex") # $4 - match type for delimiter (default "case": see $3) # Returns: # The index corresponding to the element, or -1 on failure. # ============================================================================== define i_of_element { array = $1 elem = $2 delim = "\n" if ($n_args >= 3) delim = $3 match_t = "case" if ($n_args >= 4) match_t = $4 if (delim == "") { delim = "[ \t\r\n\v\f]*" match_t = "regex" } ss_beg = 0 ss_end = 0 dd_beg = 0 dd_end = 0 found = 0 count = 0 for (dd_beg = search_string(array, delim, dd_end, "regex"), \ dd_end = $search_end; \ count >= 0; \ dd_beg = search_string(array, delim, dd_end, "regex"), \ dd_end = $search_end) { if (dd_beg == -1) { ss_end = length(array) if (substring(array, ss_beg, ss_end) == elem) { $element_start = ss_beg $element_end = ss_end return count } else return -1 } else { ss_end = dd_beg if (substring(array, ss_beg, ss_end) == elem) { $element_start = ss_beg $element_end = ss_end return count } count++ ss_beg = dd_end } } return -1 } # ============================================================================== # i_of_elempref(array, elem_pref[, delim[, match_t]]): returns the index of the # first element in the array which starts with the same string as that # passed in, using an exact match. Returns -1 on failure. # # Parameters: # $1 - the string containing all elements # $2 - the element prefix to find # $3 - the delimiter (defaults to "\n", used as "case"; if empty, # space delimiters will be used: ie "[ \t\r\n\v\f]*"/"regex") # $4 - match type for delimiter (default "case": see $3) # Returns: # The index corresponding to the element, or -1 on failure. # ============================================================================== define i_of_elempref { array = $1 elem_pref = $2 len_pref = length(elem_pref) elem = "" delim = "\n" if ($n_args >= 3) delim = $3 match_t = "case" if ($n_args >= 4) match_t = $4 if (delim == "") { delim = "[ \t\r\n\v\f]*" match_t = "regex" } ss_beg = 0 ss_end = 0 dd_beg = 0 dd_end = 0 found = 0 count = 0 for (dd_beg = search_string(array, delim, dd_end, "regex"), \ dd_end = $search_end; \ count >= 0; \ dd_beg = search_string(array, delim, dd_end, "regex"), \ dd_end = $search_end) { if (dd_beg == -1) { ss_end = length(array) elem = substring(array, ss_beg, ss_end) if (substring(elem, 0, len_pref) == elem_pref) { $element_start = ss_beg $element_end = ss_end return count } else return -1 } else { ss_end = dd_beg elem = substring(array, ss_beg, ss_end) if (substring(elem, 0, len_pref) == elem_pref) { $element_start = ss_beg $element_end = ss_end return count } count++ ss_beg = dd_end } } return -1 } # ============================================================================== # elem_of_elempref(array, elem_pref[, delim[, match_t]]): returns the first # element in the array which starts with the same string as that passed # in, using an exact match. Returns "" on failure. # # Parameters: # $1 - the string containing all elements # $2 - the element prefix to find # $3 - the delimiter (defaults to "\n", used as "case"; if empty, # space delimiters will be used: ie "[ \t\r\n\v\f]*"/"regex") # $4 - match type for delimiter (default "case": see $3) # Returns: # The corresponding element, or "" on failure. # ============================================================================== define elem_of_elempref { array = $1 elem_pref = $2 len_pref = length(elem_pref) elem = "" delim = "\n" if ($n_args >= 3) delim = $3 match_t = "case" if ($n_args >= 4) match_t = $4 if (delim == "") { delim = "[ \t\r\n\v\f]*" match_t = "regex" } ss_beg = 0 ss_end = 0 dd_beg = 0 dd_end = 0 found = 0 count = 0 for (dd_beg = search_string(array, delim, dd_end, "regex"), \ dd_end = $search_end; \ count >= 0; \ dd_beg = search_string(array, delim, dd_end, "regex"), \ dd_end = $search_end) { if (dd_beg == -1) { ss_end = length(array) elem = substring(array, ss_beg, ss_end) if (substring(elem, 0, len_pref) == elem_pref) { $element_start = ss_beg $element_end = ss_end return elem } else return "" } else { ss_end = dd_beg elem = substring(array, ss_beg, ss_end) if (substring(elem, 0, len_pref) == elem_pref) { $element_start = ss_beg $element_end = ss_end return elem } count++ ss_beg = dd_end } } return "" } # ============================================================================== # element_assoc(array, elem_pref[, delim[, match_t]]): searches for the first # element in the array which starts with the same string as that passed # in, using elem_of_elempref(). Returns the rest of the element if # successful, "" on failure. # # Parameters: # $1 - the string containing all elements # $2 - the element prefix to find # $3 - the delimiter (defaults to "\n", used as "case"; if empty, # space delimiters will be used: ie "[ \t\r\n\v\f]*"/"regex") # $4 - match type for delimiter (default "case": see $3) # Returns: # The suffix of the element, after removing $1, or "" on failure. # ============================================================================== define element_assoc { array = $1 elem_pref = $2 len_pref = length(elem_pref) elem = "" delim = "\n" if ($n_args >= 3) delim = $3 match_t = "case" if ($n_args >= 4) match_t = $4 if (delim == "") { delim = "[ \t\r\n\v\f]*" match_t = "regex" } # find our element elem = elem_of_elempref(array, elem_pref, delim, match_t) if (elem == "") return "" # adjust the start position (set earlier by elem_of_elempref) $element_start += length(elem_pref) return substring(elem, length(elem_pref)) } # ============================================================================== # element_from_to(array, i_from[, i_to[, delim[, match_t]]]): returns a new # array, holding only those elements between the specified indices. # # Parameters: # $1 - the string containing all elements # $2 - the first index (numbered from zero) # $3 - the last index (optional, defaults to the last index number if # not present or negative) # $4 - the delimiter (defaults to "\n", used as "case"; if empty, # space delimiters will be used: ie "[ \t\r\n\v\f]*"/"regex") # $5 - match type for delimiter (default "case": see $4) # Returns: # The substring of the original array, corresponding to the index range # given. Fails with an empty string. If the last index is beyond the # end of the array, this is not cause for failure. # ============================================================================== define element_from_to { array = $1 i_from = $2 i_to = -1 if ($n_args >= 3) i_to = $3 delim = "\n" if ($n_args >= 4) delim = $4 match_t = "case" if ($n_args >= 5) match_t = $5 if (delim == "") { delim = "[ \t\r\n\v\f]*" match_t = "regex" } if (i_from < 0 || (i_from > i_to && i_to >= 0)) return "" ss_beg = 0 ss_end = length(array) dd_beg = 0 dd_end = 0 found = 0 count = 0 index = i_from if (index >= 0) { for (dd_beg = search_string(array, delim, dd_end, "regex"), \ dd_end = $search_end; \ count <= index; \ dd_beg = search_string(array, delim, dd_end, "regex"), \ dd_end = $search_end) { if (count == index) { found = 1 if (dd_beg == -1 || i_to < 0) { ss_end = length(array) break } ss_end = dd_beg index++ if (index > i_to || dd_beg == -1) break } else if (dd_beg == -1) break else if (!found) { if (count < index) ss_beg = dd_end } count++ } } if (found) { $element_start = ss_beg $element_end = ss_end return substring(array, ss_beg, ss_end) } return "" }