# String utilities

This unit lives at [lib/str.fs] and provides a few strings related words.

Most strings in Dusk are regular strings as [doc/usage] describes. However, we
sometimes have to deal with null-terminated strings and this unit also has words
to deal with them. We refer to null-terminated strings as "zstr" (z for zero).

This unit also defines the concept of "string lists". Those are simply strings
following each other in memory, ending with a null string (a pointer to a byte
containing a 0). To iterate a string list, all we need to do is "skip" the
string using its size byte.

## String pool usage

Some words need to copy string contents to memory. For this they use the string
pool [doc/usage/lit]. Words needing to work on copies of string will yield
references from buffer within that pool as a result. Words with a *P* mention
use the pool.

## API

### Constants

NULLSTR  An empty string

### Words

ws? ( c -- f )
  Returns whether character "c" is a whitespace.

s) ( str -- a )
  Skip "str", that is, return the address following its last char.

str>pool ( str -- str ) *P*
  Copy "str" to the pool and yield its pool reference.

[]>str ( a u -- str ) *P*
  Copy range "a u" in the pool and return the corresponding string.

str>zstr ( str -- zstr ) *P*
  Copy "str" to pool, add a null terminator and yield zstr.

strcat ( s1 s2 -- str ) *P*
  Concatenates s1 and s2 in the pool and return the corresponding string.

s[]= ( str a u -- f )
  Compares a string to a range.

cmove+ ( src dst u -- dst+ )
  Like "cmove", but also yields "dst+u".

cmove" ( dst "x" -- a u )
  Copy bytes "x" within quotes to address "dst" and yield range "a u" of the
  copied contents.

zstrlen ( ztr -- len )
  Returns the length of "zstr".

zmove ( zsrc dst -- dst+ )
  Copies "u" bytes from zsrc where u is zstr's length, including the null byte.
  Yields "dst+u".

[str]? ( str a u -- idx )
  Search for the first occurrence of "str" in range "a u" and return its index.
  Returns -1 if not found.

sfind ( str list -- idx? f )
  Find "str" in "list" and return its index and f=1 if found, f=0 otherwise.

slistiter ( idx list -- str )
  Given a string list "list", iterate to its "idx" element and return the str.

toword ( -- c )
  Read input stream until next non WS and yield it.

expectchar ( c -- )
  Read input stream, discarding whitespaces and expect the next char to be "c"

stringlist ( n "name" "..." -- )
  Create a list of strings (same format as sfind above) with the specified
  number of elements. Elements are accumulated using "wordorquote"
  [doc/usage/io].

  Example: 3 stringlist mylist foo bar "hello world!"

rfor ( a u -- ) i=a j=idx k=u
  An iterator over the range "a u". It iterates "u" time, yielding an increased
  "a" as "i". Additionally, an index starting at 0 is maintained at "j".

  Example: " hello" c@+ rfor i c@ emit j . next --> h0e1l2l3o4

startswith? ( substr str -- f )
  Yields f=1 if "str" begins with "substr".

endswith? ( substr str -- f )
  Yields f=1 if "str" ends with "substr".

upcase ( c -- c )
  If c is between "a" and "z", yield their upcase version. Otherwise, yield c.
