Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)

lib/strings: Update documentation comments for doc generation

Updates documentation comments with extra information for nixdoc[1]
compatibility.

Some documentation strings have additionally been reworded for
clarity.

"Faux types" are added where applicable, but some functions do things
that are not trivially representable in the type notation used so they
were ignored for this purpose.

[1]: https://github.com/tazjin/nixdoc

+153 -51
+153 -51
lib/strings.nix
··· 12 13 /* Concatenate a list of strings. 14 15 Example: 16 concatStrings ["foo" "bar"] 17 => "foobar" ··· 19 concatStrings = builtins.concatStringsSep ""; 20 21 /* Map a function over a list and concatenate the resulting strings. 22 23 Example: 24 concatMapStrings (x: "a" + x) ["foo" "bar"] ··· 26 */ 27 concatMapStrings = f: list: concatStrings (map f list); 28 29 - /* Like `concatMapStrings' except that the f functions also gets the 30 position as a parameter. 31 32 Example: 33 concatImapStrings (pos: x: "${toString pos}-${x}") ["foo" "bar"] 34 => "1-foo2-bar" ··· 36 concatImapStrings = f: list: concatStrings (lib.imap1 f list); 37 38 /* Place an element between each element of a list 39 40 Example: 41 intersperse "/" ["usr" "local" "bin"] 42 => ["usr" "/" "local" "/" "bin"]. 43 */ 44 - intersperse = separator: list: 45 if list == [] || length list == 1 46 then list 47 else tail (lib.concatMap (x: [separator x]) list); 48 49 /* Concatenate a list of strings with a separator between each element 50 51 Example: 52 concatStringsSep "/" ["usr" "local" "bin"] 53 => "usr/local/bin" ··· 55 concatStringsSep = builtins.concatStringsSep or (separator: list: 56 concatStrings (intersperse separator list)); 57 58 - /* First maps over the list and then concatenates it. 59 60 Example: 61 concatMapStringsSep "-" (x: toUpper x) ["foo" "bar" "baz"] 62 => "FOO-BAR-BAZ" 63 */ 64 - concatMapStringsSep = sep: f: list: concatStringsSep sep (map f list); 65 66 - /* First imaps over the list and then concatenates it. 67 68 Example: 69 - 70 concatImapStringsSep "-" (pos: x: toString (x / pos)) [ 6 6 6 ] 71 => "6-3-2" 72 */ 73 - concatImapStringsSep = sep: f: list: concatStringsSep sep (lib.imap1 f list); 74 75 - /* Construct a Unix-style search path consisting of each `subDir" 76 - directory of the given list of packages. 77 78 Example: 79 makeSearchPath "bin" ["/root" "/usr" "/usr/local"] 80 => "/root/bin:/usr/bin:/usr/local/bin" 81 - makeSearchPath "bin" ["/"] 82 - => "//bin" 83 */ 84 - makeSearchPath = subDir: packages: 85 - concatStringsSep ":" (map (path: path + "/" + subDir) (builtins.filter (x: x != null) packages)); 86 87 - /* Construct a Unix-style search path, using given package output. 88 - If no output is found, fallback to `.out` and then to the default. 89 90 Example: 91 makeSearchPathOutput "dev" "bin" [ pkgs.openssl pkgs.zlib ] 92 => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev/bin:/nix/store/wwh7mhwh269sfjkm6k5665b5kgp7jrk2-zlib-1.2.8/bin" 93 */ 94 - makeSearchPathOutput = output: subDir: pkgs: makeSearchPath subDir (map (lib.getOutput output) pkgs); 95 96 /* Construct a library search path (such as RPATH) containing the 97 libraries for a set of packages ··· 117 118 /* Construct a perl search path (such as $PERL5LIB) 119 120 - FIXME(zimbatm): this should be moved in perl-specific code 121 - 122 Example: 123 pkgs = import <nixpkgs> { } 124 makePerlPath [ pkgs.perlPackages.libnet ] 125 => "/nix/store/n0m1fk9c960d8wlrs62sncnadygqqc6y-perl-Net-SMTP-1.25/lib/perl5/site_perl" 126 */ 127 makePerlPath = makeSearchPathOutput "lib" "lib/perl5/site_perl"; 128 129 /* Construct a perl search path recursively including all dependencies (such as $PERL5LIB) ··· 138 /* Depending on the boolean `cond', return either the given string 139 or the empty string. Useful to concatenate against a bigger string. 140 141 Example: 142 optionalString true "some-string" 143 => "some-string" 144 optionalString false "some-string" 145 => "" 146 */ 147 - optionalString = cond: string: if cond then string else ""; 148 149 /* Determine whether a string has given prefix. 150 151 Example: 152 hasPrefix "foo" "foobar" ··· 154 hasPrefix "foo" "barfoo" 155 => false 156 */ 157 - hasPrefix = pref: str: 158 - substring 0 (stringLength pref) str == pref; 159 160 /* Determine whether a string has given suffix. 161 162 Example: 163 hasSuffix "foo" "foobar" ··· 165 hasSuffix "foo" "barfoo" 166 => true 167 */ 168 - hasSuffix = suffix: content: 169 let 170 lenContent = stringLength content; 171 lenSuffix = stringLength suffix; ··· 180 Also note that Nix treats strings as a list of bytes and thus doesn't 181 handle unicode. 182 183 Example: 184 stringToCharacters "" 185 => [ ] ··· 194 /* Manipulate a string character by character and replace them by 195 strings before concatenating the results. 196 197 Example: 198 stringAsChars (x: if x == "a" then "i" else x) "nax" 199 => "nix" 200 */ 201 - stringAsChars = f: s: 202 - concatStrings ( 203 map f (stringToCharacters s) 204 ); 205 206 - /* Escape occurrence of the elements of ‘list’ in ‘string’ by 207 prefixing it with a backslash. 208 209 Example: 210 escape ["(" ")"] "(foo)" 211 => "\\(foo\\)" ··· 213 escape = list: replaceChars list (map (c: "\\${c}") list); 214 215 /* Quote string to be used safely within the Bourne shell. 216 217 Example: 218 escapeShellArg "esc'ape\nme" ··· 222 223 /* Quote all arguments to be safely passed to the Bourne shell. 224 225 Example: 226 escapeShellArgs ["one" "two three" "four'five"] 227 => "'one' 'two three' 'four'\\''five'" ··· 230 231 /* Turn a string into a Nix expression representing that string 232 233 Example: 234 escapeNixString "hello\${}\n" 235 => "\"hello\\\${}\\n\"" 236 */ 237 escapeNixString = s: escape ["$"] (builtins.toJSON s); 238 239 - /* Obsolete - use replaceStrings instead. */ 240 replaceChars = builtins.replaceStrings or ( 241 del: new: s: 242 let ··· 256 257 /* Converts an ASCII string to lower-case. 258 259 Example: 260 toLower "HOME" 261 => "home" ··· 263 toLower = replaceChars upperChars lowerChars; 264 265 /* Converts an ASCII string to upper-case. 266 267 Example: 268 toUpper "home" ··· 273 /* Appends string context from another string. This is an implementation 274 detail of Nix. 275 276 - Strings in Nix carry an invisible `context' which is a list of strings 277 representing store paths. If the string is later used in a derivation 278 attribute, the derivation will properly populate the inputDrvs and 279 inputSrcs. ··· 319 in 320 recurse 0 0; 321 322 - /* Return the suffix of the second argument if the first argument matches 323 - its prefix. 324 325 Example: 326 removePrefix "foo." "foo.bar.baz" ··· 328 removePrefix "xxx" "foo.bar.baz" 329 => "foo.bar.baz" 330 */ 331 - removePrefix = pre: s: 332 let 333 - preLen = stringLength pre; 334 - sLen = stringLength s; 335 in 336 - if hasPrefix pre s then 337 - substring preLen (sLen - preLen) s 338 else 339 - s; 340 341 - /* Return the prefix of the second argument if the first argument matches 342 - its suffix. 343 344 Example: 345 removeSuffix "front" "homefront" ··· 347 removeSuffix "xxx" "homefront" 348 => "homefront" 349 */ 350 - removeSuffix = suf: s: 351 let 352 - sufLen = stringLength suf; 353 - sLen = stringLength s; 354 in 355 - if sufLen <= sLen && suf == substring (sLen - sufLen) sufLen s then 356 - substring 0 (sLen - sufLen) s 357 else 358 - s; 359 360 - /* Return true iff string v1 denotes a version older than v2. 361 362 Example: 363 versionOlder "1.1" "1.2" ··· 367 */ 368 versionOlder = v1: v2: builtins.compareVersions v2 v1 == 1; 369 370 - /* Return true iff string v1 denotes a version equal to or newer than v2. 371 372 Example: 373 versionAtLeast "1.1" "1.0" ··· 459 /* Create a fixed width string with additional prefix to match 460 required width. 461 462 Example: 463 fixedWidthString 5 "0" (toString 15) 464 => "00015" ··· 506 && builtins.substring 0 1 (toString x) == "/" 507 && dirOf x == builtins.storeDir; 508 509 - /* Convert string to int 510 - Obviously, it is a bit hacky to use fromJSON that way. 511 512 Example: 513 toInt "1337" ··· 517 toInt "3.14" 518 => error: floating point JSON numbers are not supported 519 */ 520 toInt = str: 521 let may_be_int = builtins.fromJSON str; in 522 if builtins.isInt may_be_int 523 then may_be_int 524 else throw "Could not convert ${str} to int."; 525 526 - /* Read a list of paths from `file', relative to the `rootPath'. Lines 527 - beginning with `#' are treated as comments and ignored. Whitespace 528 - is significant. 529 530 - NOTE: this function is not performant and should be avoided 531 532 Example: 533 readPathsFromFile /prefix ··· 548 absolutePaths; 549 550 /* Read the contents of a file removing the trailing \n 551 552 Example: 553 $ echo "1.0" > ./version
··· 12 13 /* Concatenate a list of strings. 14 15 + Type: concatStrings :: [string] -> string 16 + 17 Example: 18 concatStrings ["foo" "bar"] 19 => "foobar" ··· 21 concatStrings = builtins.concatStringsSep ""; 22 23 /* Map a function over a list and concatenate the resulting strings. 24 + 25 + Type: concatMapStrings :: (a -> string) -> [a] -> string 26 27 Example: 28 concatMapStrings (x: "a" + x) ["foo" "bar"] ··· 30 */ 31 concatMapStrings = f: list: concatStrings (map f list); 32 33 + /* Like `concatMapStrings` except that the f functions also gets the 34 position as a parameter. 35 36 + Type: concatImapStrings :: (int -> a -> string) -> [a] -> string 37 + 38 Example: 39 concatImapStrings (pos: x: "${toString pos}-${x}") ["foo" "bar"] 40 => "1-foo2-bar" ··· 42 concatImapStrings = f: list: concatStrings (lib.imap1 f list); 43 44 /* Place an element between each element of a list 45 + 46 + Type: intersperse :: a -> [a] -> [a] 47 48 Example: 49 intersperse "/" ["usr" "local" "bin"] 50 => ["usr" "/" "local" "/" "bin"]. 51 */ 52 + intersperse = 53 + # Separator to add between elements 54 + separator: 55 + # Input list 56 + list: 57 if list == [] || length list == 1 58 then list 59 else tail (lib.concatMap (x: [separator x]) list); 60 61 /* Concatenate a list of strings with a separator between each element 62 63 + Type: concatStringsSep :: string -> [string] -> string 64 + 65 Example: 66 concatStringsSep "/" ["usr" "local" "bin"] 67 => "usr/local/bin" ··· 69 concatStringsSep = builtins.concatStringsSep or (separator: list: 70 concatStrings (intersperse separator list)); 71 72 + /* Maps a function over a list of strings and then concatenates the 73 + result with the specified separator interspersed between 74 + elements. 75 + 76 + Type: concatMapStringsSep :: string -> (string -> string) -> [string] -> string 77 78 Example: 79 concatMapStringsSep "-" (x: toUpper x) ["foo" "bar" "baz"] 80 => "FOO-BAR-BAZ" 81 */ 82 + concatMapStringsSep = 83 + # Separator to add between elements 84 + sep: 85 + # Function to map over the list 86 + f: 87 + # List of input strings 88 + list: concatStringsSep sep (map f list); 89 + 90 + /* Same as `concatMapStringsSep`, but the mapping function 91 + additionally receives the position of its argument. 92 93 + Type: concatMapStringsSep :: string -> (int -> string -> string) -> [string] -> string 94 95 Example: 96 concatImapStringsSep "-" (pos: x: toString (x / pos)) [ 6 6 6 ] 97 => "6-3-2" 98 */ 99 + concatImapStringsSep = 100 + # Separator to add between elements 101 + sep: 102 + # Function that receives elements and their positions 103 + f: 104 + # List of input strings 105 + list: concatStringsSep sep (lib.imap1 f list); 106 107 + /* Construct a Unix-style, colon-separated search path consisting of 108 + the given `subDir` appended to each of the given paths. 109 + 110 + Type: makeSearchPath :: string -> [string] -> string 111 112 Example: 113 makeSearchPath "bin" ["/root" "/usr" "/usr/local"] 114 => "/root/bin:/usr/bin:/usr/local/bin" 115 + makeSearchPath "bin" [""] 116 + => "/bin" 117 */ 118 + makeSearchPath = 119 + # Directory name to append 120 + subDir: 121 + # List of base paths 122 + paths: 123 + concatStringsSep ":" (map (path: path + "/" + subDir) (builtins.filter (x: x != null) paths)); 124 125 + /* Construct a Unix-style search path by appending the given 126 + `subDir` to the specified `output` of each of the packages. If no 127 + output by the given name is found, fallback to `.out` and then to 128 + the default. 129 + 130 + Type: string -> string -> [package] -> string 131 132 Example: 133 makeSearchPathOutput "dev" "bin" [ pkgs.openssl pkgs.zlib ] 134 => "/nix/store/9rz8gxhzf8sw4kf2j2f1grr49w8zx5vj-openssl-1.0.1r-dev/bin:/nix/store/wwh7mhwh269sfjkm6k5665b5kgp7jrk2-zlib-1.2.8/bin" 135 */ 136 + makeSearchPathOutput = 137 + # Package output to use 138 + output: 139 + # Directory name to append 140 + subDir: 141 + # List of packages 142 + pkgs: makeSearchPath subDir (map (lib.getOutput output) pkgs); 143 144 /* Construct a library search path (such as RPATH) containing the 145 libraries for a set of packages ··· 165 166 /* Construct a perl search path (such as $PERL5LIB) 167 168 Example: 169 pkgs = import <nixpkgs> { } 170 makePerlPath [ pkgs.perlPackages.libnet ] 171 => "/nix/store/n0m1fk9c960d8wlrs62sncnadygqqc6y-perl-Net-SMTP-1.25/lib/perl5/site_perl" 172 */ 173 + # FIXME(zimbatm): this should be moved in perl-specific code 174 makePerlPath = makeSearchPathOutput "lib" "lib/perl5/site_perl"; 175 176 /* Construct a perl search path recursively including all dependencies (such as $PERL5LIB) ··· 185 /* Depending on the boolean `cond', return either the given string 186 or the empty string. Useful to concatenate against a bigger string. 187 188 + Type: optionalString :: bool -> string -> string 189 + 190 Example: 191 optionalString true "some-string" 192 => "some-string" 193 optionalString false "some-string" 194 => "" 195 */ 196 + optionalString = 197 + # Condition 198 + cond: 199 + # String to return if condition is true 200 + string: if cond then string else ""; 201 202 /* Determine whether a string has given prefix. 203 + 204 + Type: hasPrefix :: string -> string -> bool 205 206 Example: 207 hasPrefix "foo" "foobar" ··· 209 hasPrefix "foo" "barfoo" 210 => false 211 */ 212 + hasPrefix = 213 + # Prefix to check for 214 + pref: 215 + # Input string 216 + str: substring 0 (stringLength pref) str == pref; 217 218 /* Determine whether a string has given suffix. 219 + 220 + Type: hasSuffix :: string -> string -> bool 221 222 Example: 223 hasSuffix "foo" "foobar" ··· 225 hasSuffix "foo" "barfoo" 226 => true 227 */ 228 + hasSuffix = 229 + # Suffix to check for 230 + suffix: 231 + # Input string 232 + content: 233 let 234 lenContent = stringLength content; 235 lenSuffix = stringLength suffix; ··· 244 Also note that Nix treats strings as a list of bytes and thus doesn't 245 handle unicode. 246 247 + Type: stringtoCharacters :: string -> [string] 248 + 249 Example: 250 stringToCharacters "" 251 => [ ] ··· 260 /* Manipulate a string character by character and replace them by 261 strings before concatenating the results. 262 263 + Type: stringAsChars :: (string -> string) -> string -> string 264 + 265 Example: 266 stringAsChars (x: if x == "a" then "i" else x) "nax" 267 => "nix" 268 */ 269 + stringAsChars = 270 + # Function to map over each individual character 271 + f: 272 + # Input string 273 + s: concatStrings ( 274 map f (stringToCharacters s) 275 ); 276 277 + /* Escape occurrence of the elements of `list` in `string` by 278 prefixing it with a backslash. 279 280 + Type: escape :: [string] -> string -> string 281 + 282 Example: 283 escape ["(" ")"] "(foo)" 284 => "\\(foo\\)" ··· 286 escape = list: replaceChars list (map (c: "\\${c}") list); 287 288 /* Quote string to be used safely within the Bourne shell. 289 + 290 + Type: escapeShellArg :: string -> string 291 292 Example: 293 escapeShellArg "esc'ape\nme" ··· 297 298 /* Quote all arguments to be safely passed to the Bourne shell. 299 300 + Type: escapeShellArgs :: [string] -> string 301 + 302 Example: 303 escapeShellArgs ["one" "two three" "four'five"] 304 => "'one' 'two three' 'four'\\''five'" ··· 307 308 /* Turn a string into a Nix expression representing that string 309 310 + Type: string -> string 311 + 312 Example: 313 escapeNixString "hello\${}\n" 314 => "\"hello\\\${}\\n\"" 315 */ 316 escapeNixString = s: escape ["$"] (builtins.toJSON s); 317 318 + # Obsolete - use replaceStrings instead. 319 replaceChars = builtins.replaceStrings or ( 320 del: new: s: 321 let ··· 335 336 /* Converts an ASCII string to lower-case. 337 338 + Type: toLower :: string -> string 339 + 340 Example: 341 toLower "HOME" 342 => "home" ··· 344 toLower = replaceChars upperChars lowerChars; 345 346 /* Converts an ASCII string to upper-case. 347 + 348 + Type: toUpper :: string -> string 349 350 Example: 351 toUpper "home" ··· 356 /* Appends string context from another string. This is an implementation 357 detail of Nix. 358 359 + Strings in Nix carry an invisible `context` which is a list of strings 360 representing store paths. If the string is later used in a derivation 361 attribute, the derivation will properly populate the inputDrvs and 362 inputSrcs. ··· 402 in 403 recurse 0 0; 404 405 + /* Return a string without the specified prefix, if the prefix matches. 406 + 407 + Type: string -> string -> string 408 409 Example: 410 removePrefix "foo." "foo.bar.baz" ··· 412 removePrefix "xxx" "foo.bar.baz" 413 => "foo.bar.baz" 414 */ 415 + removePrefix = 416 + # Prefix to remove if it matches 417 + prefix: 418 + # Input string 419 + str: 420 let 421 + preLen = stringLength prefix; 422 + sLen = stringLength str; 423 in 424 + if hasPrefix prefix str then 425 + substring preLen (sLen - preLen) str 426 else 427 + str; 428 + 429 + /* Return a string without the specified suffix, if the suffix matches. 430 431 + Type: string -> string -> string 432 433 Example: 434 removeSuffix "front" "homefront" ··· 436 removeSuffix "xxx" "homefront" 437 => "homefront" 438 */ 439 + removeSuffix = 440 + # Suffix to remove if it matches 441 + suffix: 442 + # Input string 443 + str: 444 let 445 + sufLen = stringLength suffix; 446 + sLen = stringLength str; 447 in 448 + if sufLen <= sLen && suffix == substring (sLen - sufLen) sufLen str then 449 + substring 0 (sLen - sufLen) str 450 else 451 + str; 452 453 + /* Return true if string v1 denotes a version older than v2. 454 455 Example: 456 versionOlder "1.1" "1.2" ··· 460 */ 461 versionOlder = v1: v2: builtins.compareVersions v2 v1 == 1; 462 463 + /* Return true if string v1 denotes a version equal to or newer than v2. 464 465 Example: 466 versionAtLeast "1.1" "1.0" ··· 552 /* Create a fixed width string with additional prefix to match 553 required width. 554 555 + This function will fail if the input string is longer than the 556 + requested length. 557 + 558 + Type: fixedWidthString :: int -> string -> string 559 + 560 Example: 561 fixedWidthString 5 "0" (toString 15) 562 => "00015" ··· 604 && builtins.substring 0 1 (toString x) == "/" 605 && dirOf x == builtins.storeDir; 606 607 + /* Parse a string string as an int. 608 + 609 + Type: string -> int 610 611 Example: 612 toInt "1337" ··· 616 toInt "3.14" 617 => error: floating point JSON numbers are not supported 618 */ 619 + # Obviously, it is a bit hacky to use fromJSON this way. 620 toInt = str: 621 let may_be_int = builtins.fromJSON str; in 622 if builtins.isInt may_be_int 623 then may_be_int 624 else throw "Could not convert ${str} to int."; 625 626 + /* Read a list of paths from `file`, relative to the `rootPath`. 627 + Lines beginning with `#` are treated as comments and ignored. 628 + Whitespace is significant. 629 630 + NOTE: This function is not performant and should be avoided. 631 632 Example: 633 readPathsFromFile /prefix ··· 648 absolutePaths; 649 650 /* Read the contents of a file removing the trailing \n 651 + 652 + Type: fileContents :: path -> string 653 654 Example: 655 $ echo "1.0" > ./version