gleipnir_line
=============



Name
----
gleip_line_empty,
gleip_line_mem,
gleip_line_mem_grow,
gleip_line_mem_grow_b,
gleip_line_mem_trim,
gleip_line_mem_trim_b,
gleip_line_add_str,
gleip_line_add_str_b,
gleip_line_add_str_back,
gleip_line_add_str_back_b,
gleip_line_add_ch,
gleip_line_add_ch_b,
gleip_line_add_ch_back,
gleip_line_add_ch_back_b,
gleip_line_rm_str,
gleip_line_rm_str_last,
gleip_line_rm_ch,
gleip_line_rm_ch_last,
gleip_line_rm_from,
gleip_line_rm_to,
gleip_line_rm,
gleip_line_cpy,
gleip_line_cpy_b,
gleip_line_alloc_mem,
gleip_line_alloc_len,
gleip_line_alloc,
gleip_line_alloc_cpy - gleipnir_line.



Synopsis
--------
	long GLEIP_LINE_VERSION;

	int
	gleip_line_empty (
		const char	* const restrict line
		);

	size_t
	gleip_line_mem (
		const char	* const restrict line
		);

	char *
	gleip_line_mem_grow (
		char		* line,
		const size_t	mem
		);

	int
	gleip_line_mem_grow_b (
		char		* * const line,
		const size_t	mem
		);

	char *
	gleip_line_mem_trim (
		char		* line
		);

	int
	gleip_line_mem_trim_b (
		char		* * const line
		);

	char *
	gleip_line_add_str (
		char		* line,
		const char	* const src,
		const size_t	i
		);

	int
	gleip_line_add_str_b (
		char		* * const line,
		const char	* const src,
		const size_t	i
		);

	char *
	gleip_line_add_str_back (
		char		* line,
		const char	* const src
		);

	int
	gleip_line_add_str_back_b (
		char		* * const line,
		const char	* const src
		);

	char *
	gleip_line_add_ch (
		char		* line,
		const char	ch,
		const size_t	i
		);

	int
	gleip_line_add_ch_b (
		char		* * const line,
		const char	ch,
		const size_t	i
		);

	char *
	gleip_line_add_ch_back (
		char		* line,
		const char	ch
		);

	int
	gleip_line_add_ch_back_b (
		char		* * const line,
		const char	ch
		);

	void
	gleip_line_rm_str (
		char		* restrict line,
		const size_t	i,
		const size_t	len
		);

	void
	gleip_line_rm_str_last (
		char		* restrict line,
		const size_t	len
		);

	void
	gleip_line_rm_ch (
		char		* restrict line,
		const size_t	i
		);

	void
	gleip_line_rm_ch_last (
		char		* restrict line
		);

	void
	gleip_line_rm_from (
		char		* restrict line,
		const size_t	i
		);

	void
	gleip_line_rm_to (
		char		* restrict line,
		const size_t	len
		);

	void
	gleip_line_rm (
		char		* restrict line
		);

	char *
	gleip_line_cpy (
		char		* line,
		const char	* const src
		);

	int
	gleip_line_cpy_b (
		char		* * const line,
		const char	* const src
		);

	char *
	gleip_line_alloc_mem (
		const size_t	mem
		);

	char *
	gleip_line_alloc_len (
		const size_t	len
		);

	char *
	gleip_line_alloc (void);

	char *
	gleip_line_alloc_cpy (
		const char	* const src
		);



Options
-------

`line`
:	The growable C-string to operate on. For the `*_b` functions,
	this is a pointer to a growable C-string.

`mem`
:	The memory of the growable C-string. Must be `≥ 2`.

`i`
:	Index in `line`.

`src`
:	C-string to copy into `line`. `src` may alias `line`, `src`
	doesn't necessarily have to be a growable C-string, and it may
	be read-only storage.

`ch`
:	Character to copy into `line`. May not be `'\0'`.

`len`
:	The amount of characters to remove or allocate.



Description
-----------
Growable C-strings are dynamically allocated C-strings that can grow.
They can not be in read-only or automatically allocated memory, because
`realloc` will be called on them to increase their length. Furthermore,
all `char`s after the first `'\0'` must be `'\0'`, and the last two
`char`s must be `"\0\n"`. To make sure that this is always the case, you
should use the supplied allocation functions to allocate the strings.
You can use `sprintf` and similar functions to modify the strings as
long as you don't violate these rules. `strtok` should not be used since
it mangles the string with `'\0'` characters (you can use
`gleip_lineread_raw_cstr` or `gleip_lineread_raw_eof_cstr` in
`gleipnir_lineread`(7) for tokenization).

All functions operate on single bytes, but can be used on multibyte
strings. For example, `gleip_line_rm_ch` does not attempt to guess if
you want to remove a single byte or a UTF-8 or other symbol consisting
of several bytes. You have to determine that yourself.

`GLEIP_LINE_VERSION` is the version of the library.

`gleip_line_empty` returns whether the string is empty. It's empty if
the first `char` is `\0`.

`gleip_line_mem` returns the memory of a growable C-string.

`gleip_line_mem_grow` grows `line` to `mem`.

`gleip_line_mem_trim` trims `line` to the minimum amount of memory
required to hold all the characters in it. Doing this will probably only
lead to heap fragmentation.

`gleip_line_add_str` adds `src` into `line` at index `i`, and shifts the
characters that were at `i` to the right. If `i` is equal to
`strlen(line)`, then the characters are appended at the end of the
string.

`gleip_line_add_str_back` appends `src` at the end of `line`.

`gleip_line_add_ch` is like `gleip_line_add_str` except that it adds a
single character.

`gleip_line_add_ch_back` is like `gleip_line_add_ch` but appends the
character at the end of `line`.

`gleip_line_rm_str` removes `len` characters in `line` starting at index
`i`. Removing characters beyond the length of the string is not allowed.

`gleip_line_rm_str_last` removes `len` characters at the end of `line`.
Removing characters beyond the length of the string is not allowed.

`gleip_line_rm_ch` removes the character at `i` in `line`.

`gleip_line_rm_ch_last` removes the last character in `line`.

`gleip_line_rm_from` removes all characters in `line` starting from
index `i`.

`gleip_line_rm_to` removes `len` characters in `line` starting from
index 0.

`gleip_line_rm` removes all characters in `line`.

`gleip_line_cpy` copies `src` into `line`.

`gleip_line_alloc_mem` allocates a new growable C-string consisting of
`mem` bytes.

`gleip_line_alloc_len` allocates a new growable C-string with room for
`len` characters. This is the same as `gleip_line_alloc_mem(len + 2)`.

`gleip_line_alloc` allocates a new growable C-string with default memory
capacity. This is the same as `gleip_line_alloc_len(9)`.

`gleip_line_alloc_cpy` allocates a new growable C-string (with no more
memory than necessary) and copies `src` into it.

When you use the functions that return `char *`, you need a temporary
variable for the return value. Sometimes it's convenient if they could
return a boolean instead. Therefore the following functions do that, and
`line` is a pointer to a growable C-string. Other than that they work
exactly like the corresponding functions described above.

*	`gleip_line_mem_grow_b`
*	`gleip_line_mem_trim_b`
*	`gleip_line_add_str_b`
*	`gleip_line_add_str_back_b`
*	`gleip_line_add_ch_b`
*	`gleip_line_add_ch_back_b`
*	`gleip_line_cpy_b`



Exit status
-----------
*	Allocation functions (`gleip_line_alloc*`) return a pointer to a
	growable C-string which must be freed by the caller with
	`free()`.
*	Non-allocation functions return a pointer to the line. This can
	be a new pointer (if the string had to be re-allocated and the
	old memory region couldn't grow), the old pointer (if the string
	didn't have to grow, or if re-allocating could grow the old
	memory region), or `NULL` for failure to re-allocate. On a
	non-`NULL` return, you should always update the old pointer with
	the returned one since the old one may be invalid.
*	The `*_b` functions return a boolean. `true` (1) means success
	and `false` (0) means failure. (1 is always returned for
	`true`.)



Examples
--------
	char	* line	= gleip_line_alloc(),
		* tmp	= NULL;
	if	(NULL == line)
	{
		/*
		 * Failure to allocate.
		 */
		return	EXIT_FAILURE;
	}
	tmp	= gleip_line_cpy(line, "För Sverige — i tiden");
	if	(NULL == tmp)
	{
		/*
		 * Failure to grow (re-allocate); `line` is still valid.
		 */
		free	(line);
		return	EXIT_FAILURE;
	}
	/*
	 * `line` may be invalid and must be updated.
	 */
	line	= tmp;
	(void)puts(line);
	free	(line);
	return	EXIT_SUCCESS;

	char	* line	= gleip_line_alloc();
	if	(NULL == line)
	{
		/*
		 * Failure to allocate.
		 */
		return	EXIT_FAILURE;
	}
	if	(!gleip_line_cpy_b(& line, "För Sverige — i tiden"))
	{
		/*
		 * Failure to grow (re-allocate).
		 */
		free	(line);
		return	EXIT_FAILURE;
	}
	(void)puts(line);
	free	(line);
	return	EXIT_SUCCESS;



Diagnostics
-----------
Functions can only fail for one reason: failure to allocate or
re-allocate memory. In this case they return false or `NULL`. A true or
non-`NULL` return value always indicates success.



Details
-------
The length of a growable C-string is terminated by `'\0'` as with
ordinary C-strings. Therefore most C library functions, such as `strlen`
and all the printing functions, can be used on the growable strings.

The memory capacity of a growable C-string is terminated by the sequence
`"\0\n"`. The characters after the first `'\0'` are unused characters
that may be overwritten later. The unused characters are all set to
`'\0'` by these functions to prevent the sequence `"\0\n"` from
accidentally occurring among the unused characters.

	/*
	 * Error checking omitted.
	 */
	char	* line	= gleip_line_alloc_cpy	("abcdefg");
	/*
	 * "abcdefg\0\n"
	 *
	 * strlen = 7
	 * memory = 9
	 */
	line		= gleip_line_mem_grow	(line, 12);
	/*
	 * "abcdefg\0\0\0\0\n"
	 *
	 * strlen = 7
	 * memory = 12
	 */



Bugs
----
The fetter shall burst at Ragnarök, and the Wolf runs free.



See also
--------
`gleipnir_lines`(7),
`gleipnir_lineread`(7),
`gleipnir_lang`(7)



Homepage
--------
`www.tafl.se/gleipnir`



Author
------
Alexander Söderlund, Sweden
`<soderlund` **at** `tafl` **dot** `se>`



Copyright
---------
© 2013-2014 Alexander Söderlund, Sweden



License and warranty
--------------------
Copyright © 2013-2014 Alexander Söderlund, Sweden

Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

