gleipnir_lines
==============



Namn
----
struct gleip_lines,
gleip_lines_get_ro,
gleip_lines_get,
gleip_lines_get_ptr,
gleip_lines_mem,
gleip_lines_size,
gleip_lines_empty,
gleip_lines_mem_trim,
gleip_lines_mem_grow,
gleip_lines_addcpy,
gleip_lines_addcpy_back,
gleip_lines_addref,
gleip_lines_addref_back,
gleip_lines_rm_range,
gleip_lines_rm_range_back,
gleip_lines_rm_line,
gleip_lines_rm_line_back,
gleip_lines_rm,
gleip_lines_shift,
gleip_lines_new,
gleip_lines_new_back,
gleip_lines_new_line,
gleip_lines_new_line_back,
gleip_lines_mv_range,
gleip_lines_mv_range_back,
gleip_lines_mv,
gleip_lines_mv_back,
gleip_lines_mv_line,
gleip_lines_mv_line_back,
gleip_lines_cpy_range,
gleip_lines_cpy_range_back,
gleip_lines_cpy,
gleip_lines_cpy_back,
gleip_lines_cpy_line,
gleip_lines_cpy_line_back,
gleip_lines_free,
gleip_lines_alloc_mem,
gleip_lines_alloc,
gleip_lines_alloc_mv_range,
gleip_lines_alloc_mv_line,
gleip_lines_alloc_cpy_range,
gleip_lines_alloc_cpy,
gleip_lines_alloc_cpy_line - gleipnir_lines.



Sammanfattning
--------------
	long GLEIP_LINES_VERSION;

	struct gleip_lines
	{
		size_t	size,
			mem;
		char	* * arr;
	};

	const char *
	gleip_lines_get_ro (
		const struct gleip_lines	* const restrict lines,
		const size_t			i
		);

	char *
	gleip_lines_get (
		struct gleip_lines	* const restrict lines,
		const size_t		i
		);

	char * *
	gleip_lines_get_ptr (
		struct gleip_lines	* const restrict lines,
		const size_t		i
		);

	size_t
	gleip_lines_mem (
		const struct gleip_lines	* const restrict lines
		);

	size_t
	gleip_lines_size (
		const struct gleip_lines	* const restrict lines
		);

	int
	gleip_lines_empty (
		const struct gleip_lines	* const restrict lines
		);

	int
	gleip_lines_mem_trim (
		struct gleip_lines	* const restrict lines
		);

	int
	gleip_lines_mem_grow (
		struct gleip_lines	* const restrict lines,
		const size_t		mem
		);

	int
	gleip_lines_addcpy (
		struct gleip_lines	* const restrict lines,
		const char		* const restrict line,
		const size_t		i
		);

	int
	gleip_lines_addcpy_back (
		struct gleip_lines	* const restrict lines,
		const char		* const restrict line
		);

	int
	gleip_lines_addref (
		struct gleip_lines	* const restrict lines,
		char			* const restrict ref,
		const size_t		i
		);

	int
	gleip_lines_addref_back (
		struct gleip_lines	* const restrict lines,
		char			* const restrict ref
		);

	void
	gleip_lines_rm_range (
		struct gleip_lines	* const restrict lines,
		size_t			i,
		const size_t		count
		);

	void
	gleip_lines_rm_range_back (
		struct gleip_lines	* const restrict lines,
		const size_t		count
		);

	void
	gleip_lines_rm_line (
		struct gleip_lines	* const restrict lines,
		const size_t		i
		);

	void
	gleip_lines_rm_line_back (
		struct gleip_lines	* const restrict lines
		);

	void
	gleip_lines_rm (
		struct gleip_lines	* const restrict lines
		);

	void
	gleip_lines_shift (
		struct gleip_lines	* const restrict lines,
		const size_t		i_to,
		const size_t		i_from,
		const size_t		count
		);

	int
	gleip_lines_new (
		struct gleip_lines	* const restrict lines,
		const size_t		i,
		const size_t		count
		);

	int
	gleip_lines_new_back (
		struct gleip_lines	* const restrict lines,
		const size_t		count
		);

	int
	gleip_lines_new_line (
		struct gleip_lines	* const restrict lines,
		const size_t		i
		);

	int
	gleip_lines_new_line_back (
		struct gleip_lines	* const restrict lines
		);

	int
	gleip_lines_mv_range (
		struct gleip_lines	* const restrict dst,
		struct gleip_lines	* const restrict src,
		const size_t		i_dst,
		const size_t		i_src,
		const size_t		count
		);

	int
	gleip_lines_mv_range_back (
		struct gleip_lines	* const restrict dst,
		struct gleip_lines	* const restrict src,
		const size_t		i_src,
		const size_t		count
		);

	int
	gleip_lines_mv (
		struct gleip_lines	* const restrict dst,
		struct gleip_lines	* const restrict src,
		const size_t		i_dst
		);

	int
	gleip_lines_mv_back (
		struct gleip_lines	* const restrict dst,
		struct gleip_lines	* const restrict src
		);

	int
	gleip_lines_mv_line (
		struct gleip_lines	* const restrict dst,
		struct gleip_lines	* const restrict src,
		const size_t		i_dst,
		const size_t		i_src
		);

	int
	gleip_lines_mv_line_back (
		struct gleip_lines	* const restrict dst,
		struct gleip_lines	* const restrict src,
		const size_t		i_src
		);

	int
	gleip_lines_cpy_range (
		struct gleip_lines		* const restrict dst,
		const struct gleip_lines	* const restrict src,
		const size_t			i_dst,
		const size_t			i_src,
		const size_t			count
		);

	int
	gleip_lines_cpy_range_back (
		struct gleip_lines		* const restrict dst,
		const struct gleip_lines	* const restrict src,
		const size_t			i_src,
		const size_t			count
		);

	int
	gleip_lines_cpy (
		struct gleip_lines		* const restrict dst,
		const struct gleip_lines	* const restrict src,
		const size_t			i_dst
		);

	int
	gleip_lines_cpy_back (
		struct gleip_lines		* const restrict dst,
		const struct gleip_lines	* const restrict src
		);

	int
	gleip_lines_cpy_line (
		struct gleip_lines		* const restrict dst,
		const struct gleip_lines	* const restrict src,
		const size_t			i_dst,
		const size_t			i_src
		);

	int
	gleip_lines_cpy_line_back (
		struct gleip_lines		* const restrict dst,
		const struct gleip_lines	* const restrict src,
		const size_t			i_src
		);

	void
	gleip_lines_free (
		struct gleip_lines	* const restrict lines
		);

	struct gleip_lines *
	gleip_lines_alloc_mem (
		const size_t	mem
		);

	struct gleip_lines *
	gleip_lines_alloc (void);

	struct gleip_lines *
	gleip_lines_alloc_mv_range (
		struct gleip_lines	* const restrict src,
		const size_t		i_src,
		const size_t		count
		);

	struct gleip_lines *
	gleip_lines_alloc_mv_line (
		struct gleip_lines	* const restrict src,
		const size_t		i_src
		);

	struct gleip_lines *
	gleip_lines_alloc_cpy_range (
		const struct gleip_lines	* const restrict src,
		const size_t			i_src,
		const size_t			count
		);

	struct gleip_lines *
	gleip_lines_alloc_cpy (
		const struct gleip_lines	* const restrict src
		);

	struct gleip_lines *
	gleip_lines_alloc_cpy_line (
		const struct gleip_lines	* const restrict src,
		const size_t			i_src
		);



Argument
--------

`lines`
:	Bufferten som åtgärden ska utföras på.

`dst`
:	Bufferten som utvidgningsbara C-strängar flyttas eller kopieras
	till från `src`.

`src`
:	Bufferten som utvidgningsbara C-strängar flyttas eller kopieras
	från till `dst` (eller den returnerade bufferten).

`line`
:	C-strängen som ska kopieras och läggas till. Den behöver inte
	vara en utvidgningsbar C-sträng (men det är tillåtet, och likaså
	är strängar i skrivskyddat minne), och `lines` ansvarar *inte*
	för att frigöra den.

`ref`
:	C-strängen som ska läggas till. Den *måste* vara en
	utvidgningsbar C-sträng (som inte får vara i skrivskyddat minne)
	och `lines` ansvarar för att frigöra den.

`i`
:	Index i `lines`. Måste vara `< lines->size`.

`i_dst`
:	Index i `dst`. Måste vara `< lines->size`.

`i_src`
:	Index i `src`. Måste vara `< lines->size`.

`i_from`
:	Index i `lines` som strängarna skiftas från. De utvidgningsbara
	C-strängarna som är i intervallet `[i_from, i_from + count)` i
	`lines` skiftas till `i_to`. `i_from + count` måste vara
	`≤ lines->size`.

`i_to`
:	Index i `lines` som strängarna skiftas till. `i_to + count`
	måste vara `≤ lines->size`.

`count`
:	Antalet utvidgningsbara C-strängar som åtgärden utförs på. Måste
	vara > 0.

`mem`
:	Den önskade minneskapaciteten. Måste vara > 0.



Beskrivning
-----------
`GLEIP_LINES_VERSION` är bibliotekets version.

`struct gleip_lines` är en buffert av utvidgningsbara C-strängar.

*	`arr` är en ojämn matris med utvidgningsbara C-strängar.
*	`size` är antalet utvidgningsbara C-strängar i bufferten.
	-	`size` är alltid inom `[0, mem]`.
*	`mem` är längden av `arr`.
	-	`mem` är alltid inom `[size, ∞)` (där `∞` egentligen är
		`SIZE_MAX` (≥ C99) eller `(size_t)-1` (< C99)), och
		alltid > 0.

Följande regler gäller för pekare i `arr`:

*	`arr[n]` där `n` är inom `[0, size)` (förutsatt att `size > 0`):
	-	Är aldrig `NULL`.
	-	Kan ha vilken längd som helst (`strlen()`).
	-	Kan ha vilken minneskapacitet som helst
		(`gleip_line_mem()`).
*	`arr[n]` där `n` är inom `[size, mem)` (förutsatt att
	`mem > size`):
	-	Kan vara `NULL` eller inte `NULL`.
	-	Har alltid längd 0 (`strlen()`) om ej `NULL`.
	-	Kan ha vilken minneskapacitet som helst
		(`gleip_line_mem()`) om ej `NULL`.

Vanligtvis hämtar man bara strängar i `arr` som är inom `[0, size)`.
Element `≥ size` kallas för "skräp" och kan återanvändas när man lägger
till nya strängar i bufferten (för att minska antalet allokeringar och
frigöranden). När man tar bort strängar så raderas innehållet i dem (så
att `strlen() = 0`) och de flyttas till skräpindexen. Man ska i vanliga
fall inte manuellt göra något med skräpsträngar.

`gleip_lines_get_ro` är detsamma som `lines->arr[i]`. `i < lines->size`.

`gleip_lines_get` är detsamma som `lines->arr[i]`. `i < lines->size`.

`gleip_lines_get_ptr` är detsamma som `& lines->arr[i]`.
`i < lines->size`.

`gleip_lines_mem` är detsamma som `lines->mem`.

`gleip_lines_size` är detsamma som `lines->size`.

`gleip_lines_empty` returnerar huruvida `lines` är tom, vilket är fallet
om `size` är 0.

`gleip_lines_mem_trim` krymper minneskapaciteten hos alla strängar i
bufferten och minskar `mem` till `size` (eller 1 om `size` är 0). Att
göra detta kommer förmodligen enbart att leda till heapfragmentering.

`gleip_lines_mem_grow` ökar `lines->mem` till `mem`. `mem` måste vara
> 0.

`gleip_lines_addcpy` kopierar `line`, lägger till kopian i
`lines->arr[i]` och skiftar alla följande index med +1. `i` måste vara
`[0, lines->size]`. Om `i = lines->size` så läggs kopian till sist i
bufferten. Kopians minneskapacitet är precis tillräckligt stor för att
rymma alla tecken.

*	`line` kan vara vilken typ av C-sträng som helst (skrivbar
	(`char *`), skrivskyddad (`const char *`) eller utvidgningsbar).
	Om `line` har allokerats dynamiskt så överförs *inte* ansvaret
	för att frigöra den.

`gleip_lines_addcpy_back` kopierar `line` och lägger till kopian sist i
`lines`.

`gleip_lines_addref` lägger till `ref` på index `i` och skiftar alla
följande index med +1. `i` måste vara `[0, lines->size]`. Om
`i = lines->size` så läggs referensen till sist i bufferten.

*	`ref` måste vara en utvidgningsbar C-sträng, och ansvaret för
	att frigöra den överförs till `lines` (såvida inte funktionen
	misslyckas, i vilket fall ansvaret inte överförs).

`gleip_lines_addref_back` lägger till `ref` sist i `lines`.

`gleip_lines_rm_range` raderar `[i, i + count)` i `lines` och skiftar
alla följande strängar. `size` minskar med `count`, och därför måste
`count` vara `≤ size`.

`gleip_lines_rm_range_back` tar bort de sista `count` strängarna i
`lines`.

`gleip_lines_rm_line` tar bort strängen på index `i` i `lines`.

`gleip_lines_rm_line_back` tar bort den sista strängen i `lines`.

`gleip_lines_shift` skiftar `count` strängar med början på index
`i_from` i `lines` till `i_to`. Strängar emellan dessa index skiftas i
motsatt riktning. Strängar kan skiftas i vilken riktning som helst men
både `i_to + count` och `i_from + count` måste vara `≤ size`. Exempel:

	/*
	 * lines->arr:
	 *	0	"A"
	 *	1	"B"	i_to
	 *	2	"C"
	 *	3	"X"	i_from
	 *	4	"Y"
	 */
	gleip_lines_shift(lines,
			1,	/* i_to */
			3,	/* i_from */
			2);	/* count */
	/*
	 * lines->arr:
	 *	0	"A"
	 *	1	"X"
	 *	2	"Y"
	 *	3	"B"
	 *	4	"C"
	 */

	/*
	 * lines->arr:
	 *	0	"A"
	 *	1	"X"	i_from
	 *	2	"Y"
	 *	3	"B"	i_to
	 *	4	"C"
	 */
	gleip_lines_shift(lines,
			3,	/* i_to */
			1,	/* i_from */
			1);	/* count */
	/*
	 * lines->arr:
	 *	0	"A"
	 *	1	"Y"
	 *	2	"B"
	 *	3	"X"
	 *	4	"C"
	 */

`gleip_lines_new` lägger till `count` nya tomma (`strlen() = 0`)
strängar på index `i` i `lines` och skiftar alla följande strängar med
`+count`. `i` måste vara `[0, lines->size]`. Om `i = lines->size` så
läggs de nya strängarna till sist i bufferten. Alla nya strängar som
läggs till på detta sätt har förvald minneskapacitet.

`gleip_lines_new_back` lägger till `count` nya tomma strängar i
bufferten.

`gleip_lines_new_line` lägger till 1 tom sträng på `i` i bufferten.

`gleip_lines_new_line_back` lägger till 1 tom sträng sist i bufferten.

`gleip_lines_mv_range` flyttar `count` strängar från `i_src` i `src`
till `i_dst` i `dst`. Alla följande strängar i `dst` skiftas med
`+count`. `i_dst ≤ dst->size` och `i_src < src->size`. Om
`i_dst = dst->size` så flyttas strängarna längst bak i `dst`.
`count ≤ src->size`. `dst->size` ökar med `count` och `src->size`
minskar med lika mycket.

`gleip_lines_mv_range_back` fungerar som `gleip_lines_mv_range` förutom
att alla strängar flyttas till slutet av `dst`.

`gleip_lines_mv` flyttar alla strängar i `src` till `i_dst` i `dst`.

`gleip_lines_mv_back` flyttar alla strängar i `src` till slutet av
`dst`.

`gleip_lines_mv_line` flyttar strängen på `i_src` i `src` till `i_dst` i
`dst`.

`gleip_lines_mv_line_back` flyttar strängen på `i_src` i `src` till
slutet av `dst`.

`gleip_lines_cpy_range` kopierar `count` strängar från `i_src` i `src`
till `i_dst` i `dst`. Alla följande strängar i `dst` skiftas med
`+count`. `i_dst ≤ dst->size` och `i_src < src->size`. Om
`i_dst = dst->size` så flyttas raderna till slutet av `dst`.
`count ≤ src->size`. `dst->size` ökar med `count` men `src` ändras inte.
Minneskapaciteten hos kopiorna är precis tillräckligt stora för att
rymma tecknen som de innehåller.

`gleip_lines_cpy_range_back` fungerar som `gleip_lines_cpy_range` men
alla strängarna kopieras till slutet av `dst`.

`gleip_lines_cpy` kopierar alla strängar i `src` till `i_dst` i `dst`.

`gleip_lines_cpy_back` kopierar alla strängar i `src` till slutet av
`dst`.

`gleip_lines_cpy_line` kopierar strängen på `i_src` i `src` till `i_dst`
i `dst`.

`gleip_lines_cpy_line_back` kopierar strängen på `i_src` i `src` till
slutet av `dst`.

`gleip_lines_free` frigör en buffert av utvidgningsbara C-strängar och
alla strängar i `lines->arr` (alltså alla nya strängar som har
allokerats i bufferten, alla strängar som har flyttats eller kopierats
till den från en annan buffert och alla kopior och referenser som har
lagts till den).

`gleip_lines_alloc_mem` allokerar en buffert med minneskapacitet `mem`,
som måste vara > 0.

`gleip_lines_alloc` allokerar en buffert med förvald minneskapacitet
(9).

`gleip_lines_alloc_mv_range` flyttar `count` strängar från `i_src` i
`src` till en ny buffert, som returneras.

`gleip_lines_alloc_mv_line` flyttar strängen från `i_src` i `src` till
en ny buffert, som returneras.

`gleip_lines_alloc_cpy_range` kopierar `count` strängar från `i_src` i
`src` till en ny buffert, som returneras.

`gleip_lines_alloc_cpy` kopierar alla strängar i `src` till en ny
buffert, som returneras.

`gleip_lines_alloc_cpy_line` kopierar raden från `i_src` i `src` till en
ny buffert, som returneras.



Returvärde
----------
*	Allokeringsfunktioner (`gleip_lines_alloc*`) returnerar en
	pekare till en buffert med utvidgningsbara C-strängar, som måste
	frigöras av anroparen med `gleip_lines_free`.
*	Övriga funktioner returnerar ett booleskt värde. `true` (1)
	betyder att den lyckades och `false` (0) betyder att den
	misslyckades. (1 returneras alltid för `true`.)
*	Om en funktion misslyckas så "gör den ingenting", men den kan
	ändra skräpsträngar och `gleip_lines->mem`. Strängar `< size`
	och `gleip_lines->size` förblir dock som innan funktionsanropet.



Exempel
-------
	struct gleip_lines * const lines = gleip_lines_alloc();
	if	(NULL == lines)
	{
		/*
		 * Allokering misslyckades.
		 */
		return	EXIT_FAILURE;
	}
	if	(!gleip_lines_addcpy_back(lines,
			"Gloria altissimo suorum refugio")
	||	!gleip_lines_addcpy_back(lines, "Pro patria"))
	{
		/*
		 * Misslyckades med att lägga till kopior (allokera).
		 */
		gleip_lines_free(lines);
		return	EXIT_FAILURE;
	}
	assert	(2 == gleip_lines_size(lines));
	(void)puts		(gleip_lines_get_ro(lines, 0));
	(void)puts		(gleip_lines_get_ro(lines, 1));
	gleip_lines_free	(lines);
	return			EXIT_SUCCESS;



Felsökning
----------
Funktioner kan endast misslyckas på grund av misslyckad allokering eller
omallokering. I sådana fall returneras `false` eller `NULL`. `true`
eller en pekare som inte är `NULL` betyder alltid att åtgärden lyckades.



Fel
---
Fjättern skall brista vid Ragnarök, och fri varder ulven.



Se även
-------
`gleipnir_line`(7),
`gleipnir_lineread`(7),
`gleipnir_lang`(7)



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



Upphovsman
----------
Alexander Söderlund, Sverige
`<soderlund` **snabel-a** `tafl` **punkt** `se>`



Upphovsrätt
-----------
© 2013-2014 Alexander Söderlund, Sverige



Licens och garanti
------------------
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.

