gleipnir_lineread
=================



Name
----
gleip_lineread_raw,
gleip_lineread_raw_eof,
gleip_lineread_raw_file,
gleip_lineread_raw_file_nl,
gleip_lineread_cb_data_next_cstr,
gleip_lineread_raw_cstr,
gleip_lineread_raw_cstr_nl,
gleip_lineread_raw_eof_file,
gleip_lineread_raw_eof_file_nl,
gleip_lineread_raw_eof_cstr,
gleip_lineread_raw_eof_cstr_nl,
gleip_lineread_interp,
gleip_lineread_interp_def,
gleip_lineread_interp_file,
gleip_lineread_interp_file_def,
gleip_lineread_interp_cstr,
gleip_lineread_interp_cstr_def - gleipnir_lineread.



Synopsis
--------
	int
	gleip_lineread_raw (
		char	* * const dst,
		void	* const data,
		int	(* callback_data_next) (void *),
		int	(* callback_tkn_delim) (int)
		);

	int
	gleip_lineread_raw_eof (
		struct gleip_lines	* const restrict lines,
		void			* const data,
		int			(* callback_data_next) (void *),
		int			(* callback_tkn_delim) (int)
		);

	int
	gleip_lineread_raw_file (
		char	* * const dst,
		FILE	* const file,
		int	(* callback_tkn_delim) (int)
		);

	int
	gleip_lineread_raw_file_nl (
		char	* * const dst,
		FILE	* const file
		);

	int
	gleip_lineread_cb_data_next_cstr (
		const char	* * const src
		);

	int
	gleip_lineread_raw_cstr (
		char		* * const dst,
		const char	* * const src,
		int		(* callback_tkn_delim) (int)
		);

	int
	gleip_lineread_raw_cstr_nl (
		char		* * const dst,
		const char	* * const src
		);

	int
	gleip_lineread_raw_eof_file (
		struct gleip_lines	* const restrict lines,
		FILE			* const file,
		int			(* callback_tkn_delim) (int)
		);

	int
	gleip_lineread_raw_eof_file_nl (
		struct gleip_lines	* const restrict lines,
		FILE			* const file
		);

	int
	gleip_lineread_raw_eof_cstr (
		struct gleip_lines	* const restrict lines,
		const char		* * const src,
		int			(* callback_tkn_delim) (int)
		);

	int
	gleip_lineread_raw_eof_cstr_nl (
		struct gleip_lines	* const restrict lines,
		const char		* * const src
		);

	int
	gleip_lineread_interp (
		struct gleip_lines	* const restrict lines,
		void			* const data,
		const size_t		tkns_max,
		const char		condense_sym,
		int			(* callback_data_next) (void *),
		int			(* callback_tkn_delim) (int),
		int			(* callback_line_delim) (int)
		);

	int
	gleip_lineread_interp_def (
		struct gleip_lines	* const restrict lines,
		void			* const data,
		const size_t		tkns_max,
		int			(* callback_data_next) (void *)
		);

	int
	gleip_lineread_interp_file (
		struct gleip_lines	* const restrict lines,
		FILE			* const file,
		const size_t		tkns_max,
		const char		condense_sym,
		int			(* callback_tkn_delim) (int),
		int			(* callback_line_delim) (int)
		);

	int
	gleip_lineread_interp_file_def (
		struct gleip_lines	* const restrict lines,
		FILE			* const file,
		const size_t		tkns_max
		);

	int
	gleip_lineread_interp_cstr (
		struct gleip_lines	* const restrict lines,
		const char		* * const src,
		const size_t		tkns_max,
		const char		condense_sym,
		int			(* callback_tkn_delim) (int),
		int			(* callback_line_delim) (int)
		);

	int
	gleip_lineread_interp_cstr_def (
		struct gleip_lines	* const restrict lines,
		const char		* * const src,
		const size_t		tkns_max
		);



Options
-------

`dst`
:	Pointer to the destination string (to which all characters are
	appended). This must be a growable C-string.

`lines`
:	The destination string buffer. When tokenizing, each token is
	added as a growable C-string in this buffer.

`data`
:	Data source. `callback_data_next` reads characters from the data
	source. This can be, for example, a `FILE *` or a (regular)
	C-string.

`src`
:	A pointer to a regular C-string. The C-string may be in
	read-only storage. The pointer increases when iterating over
	`src`, so `(* src)[0]` will be `'\0'` when `callback_data_next`
	returns `EOF` (when the whole string has been read).

`callback_data_next`
:	This function reads the next `int` from `data`. This is either
	a `char` or `EOF`. `EOF` is either the end of the data source or
	an I/O error (which can be determined by `ferror(FILE *)` if
	`data` is a `FILE *`). If `data` is a `FILE *`, this can be
	`fgetc(FILE *)`.

`callback_tkn_delim`
:	This is an optional function pointer that determines if a `char`
	is a token delimiter. This can be, for example, `isspace(int)`.
	If `NULL`, then there is no tokenization.

`callback_line_delim`
:	This is an optional function pointer that determines if a `char`
	is a line delimiter. If so, it causes the interpretation
	function to return upon encountering such a `char`. This takes
	precedence over `callback_tkn_delim`, if both return true for
	the same `char`. If `NULL`, then the function doesn't return
	upon encountering newlines.

`tkns_max`
:	The maximum amount of tokens that the interpretation function
	will add to `lines`. If 0, then there is no limitation.

`condense_sym`
:	When the interpretation function will not add any more tokens
	due to the `tkns_max` limitation, all token characters that are
	next to each other are replaced by a single `condense_sym`. If
	`callback_tkn_delim` is `isspace(int)`, then this in frequently
	a white space. May not be `'\0'`.



Description
-----------
`GLEIP_LINEREAD_VERSION` is the version of the library.

The following symbols are `#define`d for `switch`ing:

*	`GLEIP_LINEREAD_COMMENT` is the comment symbol (`#`).
*	`GLEIP_LINEREAD_ESCAPE` is the escape symbol (`\`).
*	`GLEIP_LINEREAD_QUOTED` is the double quote symbol (`"`).
*	`GLEIP_LINEREAD_QUOTES` is the single quote symbol (`'`).

`gleip_lineread_raw` is the basic line reading function which doesn't
interpret anything (that is, all characters are appended as they are and
no character has any special meaning). You can optionally have
tokenization by giving a non-`NULL` `callback_tkn_delim` parameter (for
example `isspace(int)` or a function that returns true for `'\n'`).

`data` is read `char` by `char` by `callback_data_next` until
`callback_tkn_delim` returns true, at which point the function returns.
The token delimiter is *not* added to the growable C-string pointed to
by `dst`. The function also returns when `callback_data_next` returns
`EOF`, which is either the end of `data` or (if `data` is a `FILE *`)
possibly an I/O error. `dst` is not cleared automatically; if there are
characters in `dst`, then this function will append new characters.

This function can return `EOF` (a true value) if the end of `data` (or
an I/O error) is encountered, false for failure to allocate or true for
success. Note that `EOF` is a negative value, which is not equal to 0,
so `EOF` is true. If `data` is a `FILE *`, you can use `ferror(FILE *)`
to distinguish between end-of-file and I/O errors.

`gleip_lineread_raw_eof` is similar to `gleip_lineread_raw`, except that
it reads the whole `data` source until it returns `EOF`. If the data
source is a `FILE *`, it will either read the entire file or as much as
it can until encountering an I/O error or an out of memory condition.
Another difference is that `gleip_lineread_raw_eof` never returns `EOF`
(that would be pointless since it always reads until end-of-file). The
tokens are added as growable C-strings in `lines`. `lines` is *not*
automatically cleared before reading, and if it is not empty, then the
new lines will be appended to the end of the buffer.

All the other `gleip_lineread_raw*` functions delegate the
aforementioned functions with appropriate parameters for reading from
`FILE`s and ordinary C-strings.

`gleip_lineread_raw_file` calls `gleip_lineread_raw` with a `FILE *`
data source.

`gleip_lineread_raw_file_nl` calls `gleip_lineread_raw_file` and
tokenizes at newlines (`'\n'`).

`gleip_lineread_cb_data_next_cstr` can be used as a parameter for the
`callback_data_next` function pointer when the `data` source is a
`const char * *` (pointer to a regular C-string). This function
increases the pointer (`src`) and returns `EOF` when it encounters
`'\0'`. Note that this means that the C-string pointed to by `src` will
increase until it contains a 0-length string (`(* src)[0]` is `'\0'`),
so you may want to back up the original pointer before calling this
function (similarly to calling `fseek()` on a `FILE` to rewind it).

`gleip_lineread_raw_cstr` calls `gleip_lineread_raw` with a
`const char *` data source (`src`). Note that the `src` C-string will
increase as described above.

`gleip_lineread_raw_cstr_nl` calls `gleip_lineread_raw_cstr` and
tokenizes at newlines (`'\n'`).

`gleip_lineread_raw_eof_file` calls `gleip_lineread_raw_eof` with a
`FILE *` data source.

`gleip_lineread_raw_eof_file_nl` calls `gleip_lineread_raw_eof_file` and
tokenizes at newlines (`'\n'`).

`gleip_lineread_raw_eof_cstr` calls `gleip_lineread_raw_eof` with a
`const char *` data source (`src`). Note that the `src` C-string will
increase as described above.

`gleip_lineread_raw_eof_cstr_nl` calls `gleip_lineread_raw_eof_cstr` and
tokenizes at newlines (`'\n'`).

`gleip_lineread_interp` is the basic line reading function which
interprets special characters. This function distinguishes between
*tokens* and *newlines*. Tokens are added as growable C-strings in
`lines`, until the first interpreted newline is encountered, at which
point the function returns. `lines` is not automatically cleared upon
calling this function, but it is mandatory to do so if `tkns_max > 0`
(it is optional if `tkns_max = 0`). Like `gleip_lineread_raw`, this
function returns `EOF` for the end of the data source (or an I/O error).

*	`callback_tkn_delim` separates each C-string added to `lines`.
	The token characters are not added to `lines`. If `NULL`, then
	there is no tokenization.
	-	If no more tokens may be added (because of `tkns_max`),
		then multiple token characters between regular
		characters are condensed to a single `condense_sym`.
	-	If token characters are escaped, or appear inside single
		or double quotes, then they are added literally without
		tokenization or condensation.
	-	`tkns_max` determines the maximum amount of tokens that
		`lines` is allowed to contain upon returning. If this is
		0, then there is no limitation.
*	`callback_line_delim` determines when the function should
	return. If `NULL`, then the function doesn't check for line
	separators, and returns when the data source returns `EOF`. The
	newline character is not added to `lines`.
	-	If a newline is escaped, then it is ignored and the
		function proceeds to read past it.
	-	If `callback_tkn_delim` returns true for the same
		`char`, then `callback_line_delim` takes precedence.

The following symbols may be interpreted, in addition to line and token
delimiters:

*	`GLEIP_LINEREAD_COMMENT` (`#`) causes the rest of the line to be
	ignored. A newline symbol is defined as the character that
	causes `callback_line_delim` to return true. If
	`callback_line_delim` is `NULL`, then a comment causes the
	function to read `data` to `EOF`. Otherwise it will read `data`
	to the end of the line and then return.
*	`GLEIP_LINEREAD_ESCAPE` (`\`) can be placed before a newline
	character to ignore the newline, or it can make an interpreted
	character appended literally. In addition, you can use it to
	insert the following C escape symbols:
	-	`'\a'`
	-	`'\b'`
	-	`'\f'`
	-	`'\n'`
	-	`'\r'`
	-	`'\t'`
	-	`'\v'`
*	`GLEIP_LINEREAD_QUOTED` (`"`) causes all characters except the
	double quote and escape character to be interpreted literally.
	It also causes newline and token delimiters to be added without
	interpretation.
*	`GLEIP_LINEREAD_QUOTES` (`'`)  causes all characters except the
	single quote to be interpreted literally. It also causes newline
	and token delimiters to be added without interpretation.

All the other `gleip_lineread_interp*` functions delegate the
aforementioned function with appropriate parameters for reading from
`FILE`s and ordinary C-strings.

`gleip_lineread_interp_def` calls `gleip_lineread_interp` with default
token and line delimiters. This is `isspace(int)` and a function that
returns true for `'\n'`, respectively. The condensation symbol is a
white space.

`gleip_lineread_interp_file` calls `gleip_lineread_interp` with a
`FILE *` data source.

`gleip_lineread_interp_file_def` calls `gleip_lineread_interp_file` with
default token and line delimiters, like `gleip_lineread_interp_def`.

`gleip_lineread_interp_cstr` calls `gleip_lineread_interp` with a
`const char *` data source (`src`). Note that the `src` C-string will
increase as described above.

`gleip_lineread_interp_cstr_def` calls `gleip_lineread_interp_cstr` with
default token and line delimiters, like `gleip_lineread_interp_def`.



Exit status
-----------
*	Some functions return `EOF` to indicate the end of the data
	source. This may also be due to an I/O error if the data source
	is a `FILE *`.
	-	Note that this may be combined with a boolean return,
		because false is defined as 0, true as not 0, and `EOF`
		as a negative number. Thus `EOF` will always be boolean
		true.
*	All functions return a boolean. `true` (1) means success and
	`false` (0) means failure. (1 is always returned for `true`;
	this is guaranteed when a boolean return value can be `EOF`.)
*	Reading functions that fail may result in a partially read file.



Examples
--------
	struct gleip_lines	* lines = gleip_lines_alloc();
	if	(NULL == lines)
	{
		(void)perror("FAIL MEM");
		return	EXIT_FAILURE;
	}
	
	(void)puts("\"q\"\tQuit\nEOF\tQuit");
	do
	{
		size_t	i;
		int	retval;
	
		gleip_lines_rm	(lines);
		retval		= gleip_lineread_interp_file_def
				(lines, stdin, 0);
		if	(EOF == retval)
		{
			(void)puts	("EOF");
			break;
		}
		else if	(!retval)
		{
			(void)perror	("FAIL MEM");
			gleip_lines_free(lines);
			return	EXIT_FAILURE;
		}
	
		for	(i = 0; i < gleip_lines_size(lines); ++i)
		{
			(void)printf("%6lu\t[%s]\n",
				(unsigned long)i,
				gleip_lines_get_ro(lines, i));
		}
	}
	while	(gleip_lines_empty(lines)
	||	gleip_line_empty(gleip_lines_get_ro(lines, 0))
	||	'q' != gleip_lines_get_ro(lines, 0)[0]);
	
	gleip_lines_free(lines);
	return	EXIT_SUCCESS;



Diagnostics
-----------
Functions return false (0) for failure to allocate memory. Some
functions return `EOF`, which may indicate an I/O error if a `FILE *` is
the data source. An I/O error may always result when you pass a `FILE *`
to a function. It is up to the caller to call `ferror(FILE *)` on it to
check for errors.



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



See also
--------
`gleipnir_line`(7),
`gleipnir_lines`(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.

