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



Namn
----
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.



Sammanfattning
--------------
	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
		);



Argument
--------
`line`
:	Den utvidgningsbara C-strängen som åtgärden utförs på. I
	funktionerna som slutar på `*_b` så är detta en pekare till en
	utvidgningsbar C-sträng.

`mem`
:	Minneskapaciteten för den utvidgningsbara C-strängen. Måste vara
	`≥ 2`.

`i`
:	Index i `line`.

`src`
:	C-strängen som ska kopieras till `line`. `src` får vara ett
	alias för `line`, behöver inte nödvändigtvis vara en
	utvidgningsbar C-sträng, och får till och med peka på
	skrivskyddat minne.

`ch`
:	Tecken att kopiera till `line`. Får inte vara `'\0'`.

`len`
:	Antal tecken att ta bort eller allokera.



Beskrivning
-----------
Utvidgningsbara C-strängar är dynamiskt allokerade C-strängar som kan
växa. De får inte vara i skrivskyddat eller automatiskt allokerat minne
eftersom `realloc` kommer att användas för att öka deras längd. Vidare
gäller att alla `char` efter det första `'\0'`-tecknet måste vara `'\0'`
och de sista två tecknen måste vara `"\0\n"`. För att försäkra sig om
att så alltid är fallet bör man använda de tillhörande
allokeringsfunktionerna för att allokera strängarna. Man kan använda
`sprintf` och liknande funktioner för att ändra strängarna så länge man
inte bryter mot dessa regler. `strtok` bör inte användas eftersom det
manglar strängen med `'\0'`-tecken (man kan använda
`gleip_lineread_raw_cstr` eller `gleip_lineread_raw_eof_cstr` i
`gleipnir_lineread`(7) för uppdelning av strängar).

Alla funktioner utgår från enskilda oktetter, men kan användas med
längdvarierande teckenkodningar. Exempelvis så görs inget försök att
gissa om man vill ta bort en oktett eller en UTF-8-symbol som består av
flera oktetter när man använder `gleip_line_rm_ch`. Det får man räkna ut
själv.

`GLEIP_LINE_VERSION` är bibliotekets version.

`gleip_line_empty` returnerar huruvida strängen är tom. Den är tom om
det första tecknet är `\0`.

`gleip_line_mem` returnerar minneskapaciteten hos en utvidgningsbar
C-sträng.

`gleip_line_mem_grow` utökar minneskapaciteten hos `line` till `mem`.

`gleip_line_mem_trim` minskar minneskapaciteten i `line` till den lägsta
mängden som rymmer alla tecken. Att göra detta kommer förmodligen enbart
att leda till heapfragmentering.

`gleip_line_add_str` lägger till `src` i `line` på index `i`, och
skiftar alla tecken som tidigare var på `i` till höger. Om `i` är lika
med `strlen(line)`, så läggs tecknen till sist i strängen.

`gleip_line_add_str_back` lägger till `src` sist i `line`.

`gleip_line_add_ch` fungerar som `gleip_line_add_str` förutom att endast
ett tecken läggs till.

`gleip_line_add_ch_back` fungerar som `gleip_line_add_ch` men lägger
till tecknen sist i `line`.

`gleip_line_rm_str` tar bort `len` tecken i `line` från och med index
`i`. Man får inte ta bort tecken bortom strängens längd.

`gleip_line_rm_str_last` tar bort `len` tecken på slutet av `line`. Man
får inte ta bort tecken bortom strängens längd.

`gleip_line_rm_ch` tar bort tecknet på `i` i `line`.

`gleip_line_rm_ch_last` tar bort det sista tecknet i `line`.

`gleip_line_rm_from` tar bort alla tecken i `line` från och med index
`i`.

`gleip_line_rm_to` tar bort `len` tecken i `line` från och med index 0.

`gleip_line_rm` tar bort alla tecken i `line`.

`gleip_line_cpy` kopierar `src` till `line`.

`gleip_line_alloc_mem` allokerar en ny utvidgningsbar C-sträng bestående
av `mem` oktetter.

`gleip_line_alloc_len` allokerar en ny utvidgningsbar C-sträng som har
plats för `len` tecken. Detta är samma sak som
`gleip_line_alloc_mem(len + 2)`.

`gleip_line_alloc` allokerar en ny utvidgningsbar C-sträng med förvald
minneskapacitet. Detta är samma sak som `gleip_line_alloc_len(9)`.

`gleip_line_alloc_cpy` allokerar en ny utvidgningsbar C-sträng (med
precis så mycket minne som krävs) och kopierar `src` till den.

När man använder funktionerna som returnerar `char *` så behövs en
tillfällig variabel för returvärdet. Ibland är det bekvämt om de kunde
returnera ett booleskt värde i stället. Detta är syftet med följande
funktioner, där `line` är en pekare till en utvidgningsbar C-sträng.
Utöver det så fungerar de exakt som funktionerna som beskrivs ovan.

*	`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`



Returvärde
----------
*	Allokeringsfunktioner (`gleip_line_alloc*`) returnerar en pekare
	till den utvidgningsbara C-strängen, som måste frigöras av
	anroparen med `free()`.
*	Övriga funktioner returnerar en pekare till strängen. Detta kan
	vara en ny pekare (om strängen måste omallokeras och den gamla
	minnesregionen inte kunde växa), den gamla pekaren (om strängen
	inte behövde växa, eller om minnesregionen kunde växa vid
	omallokering), eller `NULL` om omallokeringen misslyckades.
	Om inte funktionen returnerar `NULL` så bör man alltid uppdatera
	den gamla pekaren med den som returnerades eftersom den gamla
	kan vara ogiltig.
*	`*_b`-funktionerna returnerar ett booleskt värde. `true` (1)
	betyder att åtgärden lyckades och `false` (0) betyder att den
	misslyckades. (1 returneras alltid för `true`.)



Exempel
-------
	char	* line	= gleip_line_alloc(),
		* tmp	= NULL;
	if	(NULL == line)
	{
		/*
		 * Allokering misslyckades.
		 */
		return	EXIT_FAILURE;
	}
	tmp	= gleip_line_cpy(line, "För Sverige — i tiden");
	if	(NULL == tmp)
	{
		/*
		 * Strängen kunde inte växa (omallokering misslyckades).
		 * `line` är fortfarande giltig.
		 */
		free	(line);
		return	EXIT_FAILURE;
	}
	/*
	 * `line` kan vara ogiltig och måste uppdateras.
	 */
	line	= tmp;
	(void)puts(line);
	free	(line);
	return	EXIT_SUCCESS;

	char	* line	= gleip_line_alloc();
	if	(NULL == line)
	{
		/*
		 * Allokering misslyckades.
		 */
		return	EXIT_FAILURE;
	}
	if	(!gleip_line_cpy_b(& line, "För Sverige — i tiden"))
	{
		/*
		 * Strängen kunde inte växa.
		 */
		free	(line);
		return	EXIT_FAILURE;
	}
	(void)puts(line);
	free	(line);
	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.



Detaljer
--------
Längden hos en utvidgningsbar C-sträng markeras med `'\0'`, precis som
med vanliga C-strängar. Därför kan de flesta funktionerna från C:s
standardbibliotek användas, till exempel `strlen` och alla
utskriftsfunktioner.

Minneskapaciteten hos en utvidgningsbar C-sträng avslutas med sekvensen
`"\0\n"`. Tecknen efter det första `'\0'`-tecknet används inte och kan
komma att skrivas över senare. De oanvända tecknen sätts alla till
`'\0'` av dessa funktioner för att förhindra att sekvensen `"\0\n"`
förekommer bland de oanvända tecknen av misstag.

	/*
	 * Feltester har utelämnats.
	 */
	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
	 */



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



Se även
-------
`gleipnir_lines`(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.

