< Summary - Igor Pro Universal Testing Framework

Information
Class: procedures.igortest-utils-strings
Assembly: procedures
File(s): /builds/mirror/igortest/procedures/igortest-utils-strings.ipf
Tag: 74147b3
Line coverage
49%
Covered lines: 71
Uncovered lines: 72
Coverable lines: 143
Total lines: 254
Line coverage: 49.6%
Branch coverage
62%
Covered branches: 15
Total branches: 24
Branch coverage: 62.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
IUTF_Utils_Strings#UserPrintF()100%2137.62%
IUTF_Utils_Strings#ShuffleList()100%20%
IUTF_Utils_Strings#IsPrefix()100%287.5%
IUTF_Utils_Strings#ReplaceAllRegex()100%3100%
IUTF_Utils_Strings#CountRegex()100%3100%

File(s)

/builds/mirror/igortest/procedures/igortest-utils-strings.ipf

#LineLine coverage
 1#pragma rtGlobals=3
 2#pragma rtFunctionErrors=1
 3#pragma version=1.10
 4#pragma TextEncoding="UTF-8"
 5#pragma ModuleName=IUTF_Utils_Strings
 6
 7// This pattern is used to find all placeholder in the string. This pattern consists of multiple parts:
 8// #1: ^#2#(?:3#5)?$
 9//     The full pattern.
 10// #2: (.*?)
 11//     The prefix in front of the placeholder
 12// #3: (@?#6#4)
 13//     The pattern for our placeholder including wave placeholder extension
 14// #4: %[^a-zA-Z%]*(?:[feEgGdousxXbc]|W\dP)
 15//     The pattern for placeholder that are provided to printf
 16// #5: (.*)
 17//     The pattern after the placeholder
 18// #6: (?<!%)
 19//     At this position is no % sign allowed and do not consume this char. This is used to prevent %% matching.
 20static StrConstant USER_PRINT_PATTERN = "^(.*?)(?:(@?(?<!%)%[^a-zA-Z%]*(?:[feEgGdousxXbc]|W\\dP))(.*))?$"
 21
 22/// @brief Formats the provided string with the arguments using printf. This allows a higher flexibility
 23/// as such as it supports are flexible number of arguments and custom extensions. @n
 24/// It is required to use all provided arguments in the format string. @n
 25/// If for some reasons the conversion failed the parameter err is set different to 0 and the error message is
 26/// returned.
 27/// @param      format   The format string with the parameter placeholder
 28/// @param      strings  The wave of strings that are used for the placeholder
 29/// @param      numbers  The wave of numbers that are used for the placeholder
 30/// @param[out] err      Set different to 0 if an error during conversion happens. Set to 0 if the conversion succeeds.
 31/// @returns             The formated message if succeeds. The error message if failed.
 19532static Function/S UserPrintF(format, strings, numbers, err)
 33  string    format
 34  WAVE/T    strings
 35  WAVE      numbers
 36  variable &err
 37
 19538  string part1, part2, part3, str
 19539  variable num, i, stringIndex, numberIndex
 19540  variable stringLength = DimSize(strings, UTF_ROW)
 19541  variable numberLength = DimSize(numbers, UTF_ROW)
 19542  string   result       = ""
 43
 19544  err = 0
 45
 19546  if(GetRTError(0))
 047    sprintf result, "Pending RTE detected: \"%s\" in \"%s\"", GetRTErrMessage(), GetRTStackInfo(3)
 048    err = 1
 049    return result
 19550  endif
 51
 19552  for(; !IUTF_Utils#IsEmpty(format);)
 22553    SplitString/E=USER_PRINT_PATTERN format, part1, part2, part3
 22554    num = V_flag
 55
 22556    if(num < 1)
 057      break
 22558    endif
 59
 22560    sprintf str, part1; err = GetRTError(1)
 22561    if(err)
 062      sprintf str, "PrintF failed: format=\"%s\", err=%d", part1, err
 063      return str
 22564    endif
 22565    result += str
 66
 22567    if(num < 2)
 19568      break
 3069    endif
 70
 3071    if(!CmpStr(part2[0], "@"))
 072      part2 = part2[1, Inf]
 073      if(!CmpStr(part2, "%s"))
 74
 075        if(stringIndex > 0)
 076          err = 1
 077          return "Cannot use full string wave if single entries are used"
 078        endif
 79
 080        result += "{"
 081        for(i = 0; i < stringLength; i += 1)
 082          if(i > 0)
 083            result += ", "
 084          endif
 085          result += strings[i]
 086        endfor
 087        result += "}"
 88
 089        stringIndex = stringLength
 90
 091      else
 92
 093        if(numberIndex > 0)
 094          err = 1
 095          return "Cannot use full number wave if single entries are used"
 096        endif
 97
 098        result += "{"
 099        for(i = 0; i < numberLength; i += 1)
 0100          if(i > 0)
 0101            result += ", "
 0102          endif
 103
 0104          sprintf str, part2, numbers[i]; err = GetRTError(1)
 0105          if(err)
 0106            sprintf str, "Cannot format number %d (%g) using format \"%s\"", i, numbers[i], part2
 0107            return str
 0108          endif
 0109          result += str
 0110        endfor
 0111        result += "}"
 112
 0113        numberIndex = numberLength
 114
 0115      endif
 30116    else
 30117      if(!CmpStr(part2, "%s"))
 118
 30119        if(stringIndex >= stringLength)
 0120          err = 1
 0121          sprintf str, "Cannot load string %d, only %d are provided", stringIndex, stringLength
 0122          return str
 30123        endif
 124
 30125        result      += strings[stringIndex]
 30126        stringIndex += 1
 127
 0128      else
 129
 0130        if(numberIndex >= numberLength)
 0131          err = 1
 0132          sprintf str, "Cannot load number %d, only %d are provided", numberIndex, numberLength
 0133          return str
 0134        endif
 135
 0136        sprintf str, part2, numbers[numberIndex]; err = GetRTError(1)
 0137        if(err)
 0138          sprintf str, "Cannot format number %d (%g) using format \"%s\"", numberIndex, numbers[numberIndex], part2
 0139          return str
 0140        endif
 141
 0142        result      += str
 0143        numberIndex += 1
 144
 30145      endif
 30146    endif
 147
 30148    format = part3
 149
 30150  endfor
 151
 195152  if(stringIndex < stringLength)
 0153    err = 1
 0154    sprintf str, "Only %d out of %d strings are consumed", stringIndex, stringLength
 0155    return str
 195156  endif
 195157  if(numberIndex < numberLength)
 0158    err = 1
 0159    sprintf str, "Only %d out of %d numbers are consumed", numberIndex, numberLength
 0160    return str
 195161  endif
 162
 195163  return result
 195164End
 165
 166/// @brief Shuffles the contents of a list with the best PRNG for the current Igor version.
 167///
 168/// @param list       The list that is requested to be shuffled
 169/// @param separator  (optional, default ";") the separator of the list elements
 170///
 171/// @returns The shuffled list
 0172static Function/S ShuffleList(list, [separator])
 173  string list, separator
 174
 0175  string result
 176
 0177  separator = SelectString(ParamIsDefault(separator), separator, ";")
 178
 0179  WAVE/T wv = ListToTextWave(list, separator)
 0180  IUTF_Utils_Waves#InPlaceShuffleText1D(wv)
 0181  wfprintf result, "%s" + separator, wv
 182
 0183  return result
 0184End
 185
 186/// Returns 1 if text starts with prefix, 0 otherwise.
 45187static Function IsPrefix(text, prefix)
 188  string text, prefix
 189
 45190  variable textLength   = strlen(text)
 45191  variable prefixLength = strlen(prefix)
 192
 45193  if(textLength < prefixLength)
 0194    return 0
 45195  endif
 196
 45197  return !CmpStr(text[0, prefixLength - 1], prefix)
 45198End
 199
 200/// @brief Search for all matches of the specified regex in the text and replaces it with the
 201/// replacement
 202///
 203/// @param regex        The regular string that is used to find the text to replace. This string is
 204///                     not allowed to contain capture groups
 205/// @param text         The text to search in
 206/// @param replacement  The text that should be placed for all matches
 207///
 208/// @return The new text with all matches replaced
 660209static Function/S ReplaceAllRegex(regex, text, replacement)
 210  string regex, text, replacement
 211
 660212  string part1, part2, part3
 660213  string result = ""
 214
 660215  for(; !IUTF_Utils#IsEmpty(text);)
 660216    SplitString/E=("^(.*?)(" + regex + ")(.*)$") text, part1, part2, part3
 217
 660218    if(!V_flag)
 585219      return result + text
 75220    endif
 221
 75222    result += part1 + replacement
 75223    text    = part3
 75224  endfor
 225
 75226  return result
 660227End
 228
 229/// @brief Count the number of matches of a regex in the specified text.
 230///
 231/// @param regex        The regular string that is used to count matches. This string is not allowed
 232///                     to contain capture groups
 233/// @param text         The text to search in
 234///
 235/// @return The number of matches
 240236static Function CountRegex(regex, text)
 237  string regex, text
 238
 240239  string part1, part2, part3
 240240  variable count
 241
 240242  for(; !IUTF_Utils#IsEmpty(text);)
 365243    SplitString/E=("^(.*?)(" + regex + ")(.*)$") text, part1, part2, part3
 244
 365245    if(!V_flag)
 190246      return count
 175247    endif
 248
 175249    count += 1
 175250    text   = part3
 175251  endfor
 252
 50253  return count
 240254End