gleipnir_lang
=============



Namn
----
struct gleip_lang,
gleip_lang_size,
gleip_lang_key,
gleip_lang_value,
gleip_lang_mem_trim,
gleip_lang_get,
gleip_lang_getany,
gleip_lang_invalid_why,
gleip_lang_valid,
gleip_lang_clear,
gleip_lang_read,
gleip_lang_read_file,
gleip_lang_read_cstr,
gleip_lang_isreg,
gleip_lang_regcpy,
gleip_lang_regref,
gleip_lang_unreg_i,
gleip_lang_unreg,
gleip_lang_unreg_all,
gleip_lang_print,
gleip_lang_cpy,
gleip_lang_free,
gleip_lang_alloc_mem,
gleip_lang_alloc_cpy,
gleip_lang_alloc - gleipnir_lang.



Sammanfattning
--------------
	long	GLEIP_LANG_VERSION;

	struct gleip_lang
	{
		struct gleip_lines	* keys,
					* values;
	};

	size_t
	gleip_lang_size (
		const struct gleip_lang	* const restrict lang
		);

	const char *
	gleip_lang_key (
		const struct gleip_lang	* const restrict lang,
		const size_t		i
		);

	const char *
	gleip_lang_value (
		const struct gleip_lang	* const restrict lang,
		const size_t		i
		);

	int
	gleip_lang_mem_trim (
		struct gleip_lang	* const restrict lang
		);

	const char *
	gleip_lang_get (
		const struct gleip_lang	* const restrict lang,
		const char		* const restrict key
		);

	const char *
	gleip_lang_getany (
		const struct gleip_lang	* const restrict lang,
		const char		* const restrict key
		);

	const char *
	gleip_lang_invalid_why (
		const struct gleip_lang	* const restrict lang
		);

	int
	gleip_lang_valid (
		const struct gleip_lang	* const restrict lang
		);

	void
	gleip_lang_clear (
		struct gleip_lang	* const restrict lang
		);

	int
	gleip_lang_read (
		struct gleip_lang	* const restrict lang,
		void			* const data,
		struct gleip_lines	* restrict buf,
		int			* const restrict valid,
		int			(* callback_data_next) (void *)
		);

	int
	gleip_lang_read_file (
		struct gleip_lang	* const restrict lang,
		FILE			* const file,
		struct gleip_lines	* restrict buf,
		int			* const restrict valid
		);

	int
	gleip_lang_read_cstr (
		struct gleip_lang	* const restrict lang,
		const char		* * const src,
		struct gleip_lines	* restrict buf,
		int			* const restrict valid
		);

	int
	gleip_lang_isreg (
		const struct gleip_lang	* const restrict lang,
		const char		* const key
		);

	int
	gleip_lang_regcpy (
		struct gleip_lang	* const restrict lang,
		const char		* const key
		);

	int
	gleip_lang_regref (
		struct gleip_lang	* const restrict lang,
		char			* const ref
		);

	void
	gleip_lang_unreg_i (
		struct gleip_lang	* const restrict lang,
		const size_t		i
		);

	void
	gleip_lang_unreg (
		struct gleip_lang	* const restrict lang,
		const char		* const key
		);

	void
	gleip_lang_unreg_all (
		struct gleip_lang	* const restrict lang
		);

	int
	gleip_lang_print (
		const struct gleip_lang	* const restrict lang,
		FILE			* const restrict out,
		const char		sep
		);

	int
	gleip_lang_cpy (
		struct gleip_lang	* const restrict lang,
		const struct gleip_lang	* const restrict orig
		);

	void
	gleip_lang_free (
		struct gleip_lang	* const restrict lang
		);

	struct gleip_lang *
	gleip_lang_alloc_mem (
		const size_t	mem
		);

	struct gleip_lang *
	gleip_lang_alloc_cpy (
		const struct gleip_lang	* const restrict orig
		);

	struct gleip_lang *
	gleip_lang_alloc (void);



Argument
--------

`lang`
:	Språkposten som åtgärden ska utföras på.

`orig`
:	Språkposten som man kopierar från.

`i`
:	Index för en nyckel eller ett värde som ska hämtas. Detta måste
	vara `< gleip_lang_size(lang)`.

`key`
:	Nyckeln som åtgärden ska utföras på. Detta är en vanlig C-sträng
	som kan vara skrivskyddad.

`ref`
:	Nyckeln som ska registreras som referens. Detta *måste* vara en
	utvidgningsbar C-sträng, och ansvaret att frigöra den överförs
	till `lang`.

`data`
:	Se `gleipnir_lineread`(7).

`callback_data_next`
:	Se `gleipnir_lineread`(7).

`file`
:	Se `gleipnir_lineread`(7).

`src`
:	Se `gleipnir_lineread`(7).

`buf`
:	En buffert som man kan ge till inläsningsfunktionerna. Detta
	argument är valfritt och om den är `NULL` så allokeras en ny
	buffert för ändamålet som frigörs innan funktionen returnerar.
	Om den inte är `NULL` så använder funktionen bufferten för att
	läsa från datakällan, men funktionen övertar inte ansvaret för
	att frigöra den.

`valid`
:	En pekare till ett booleskt värde. Denna sätts till sant om
	språkfilen som lästes in var giltig, eller till falskt om den
	inte var det. Det är tillåtet att ge en `NULL`-parameter här om
	man inte bryr sig.

`out`
:	Strömmen eller filen som språkposten ska skrivas till.

`sep`
:	Tecknet som avskiljer varje språknyckel som skrivs ut. Detta kan
	vara vilken `char` som helst, till och med `'\0'`. Om tecknet är
	`'\n'` så skrivs de ut med en nyckel per rad.

`mem`
:	Språkpostens minneskapacitet. Detta är hur många nycklar som den
	kan innehålla utan att behöva växa. Måste vara > 0.



Beskrivning
-----------
**Observera att alla funktioner i `gleipnir_lang` helt enkelt itererar
över alla språknycklar och jämför dem med `strcmp` när man hämtar
översatta strängar. Det är inte effektivt, och det rekommenderas enbart
när man har ett relativt litet antal språknycklar. Eftersom nycklar är
unika så vore det mycket lämpligt att använda en hashtabell i stället om
man ett stort antal nycklar.**

En språkpost avbildar nycklar till värden. Nycklarna förändras aldrig.
Värdena är de översatta språksträngarna. Värdena kan läsas från filer
och en fil borde innehålla alla hopparningar av nycklar och värden för
ett språk.

`GLEIP_LANG_VERSION` är bibliotekets version.

`struct gleip_lang` bör betraktas som en abstrakt datatyp.

`gleip_lang_size` returnerar antalet registrerade språknycklar.

`gleip_lang_key` hämtar språknyckeln på index `i`.
`i < gleip_lang_size(lang)`. Den returnerade nyckeln är aldrig `NULL`.

`gleip_lang_value` hämtar den översatta språksträngen på index `i`.
`i < gleip_lang_size(lang)`. Det returnerade värdet är `NULL` om det
inte har lästs in, eller inte `NULL` (och inte en tom sträng) om det har
lästs in.

`gleip_lang_mem_trim` krymper minnesanvändningen till det minsta som
rymmer alla nycklar och värden.

`gleip_lang_get` returnerar den översatta språksträngen som hör ihop med
`key`. `key` *måste* ha registrerats. Det returnerade värdet är en
utvidgningsbar (men skrivskyddad) C-sträng. Om värdet inte har lästs in
så är det `NULL`. Om värdet har lästs in så är det en sträng som inte är
tom.

Observera att det är ett programmeringsfel att anropa denna funktion med
en nyckel som inte har registrerats. `gleip_lang_isreg` kan användas för
att kolla om en nyckel har registrerats.

`gleip_lang_getany` liknar `gleip_lang_get`, men om värdet inte har
lästs in så returneras i stället nyckeln (parametern). Alltså returnerar
denna funktion aldrig `NULL`.

`gleip_lang_invalid_why` returnerar nyckeln för det första värdet i
språkposten som inte har lästs in. Om alla värden har lästs in så
returnerar denna funktion `NULL`.

`gleip_lang_valid` returnerar sant om alla värden har lästs in. Om den
returnerar falskt så garanteras `gleip_lang_invalid_why` returnera en
nyckel som inte är `NULL`. Observera att denna funktion enbart kan
avgöra om alla värden finns på plats; `gleip_lang_read` kan upptäcka
andra fel i språkfiler.

`gleip_lang_clear` raderar alla värden så att `gleip_lang_get` kommer
att returnera `NULL` för alla registrerade nycklar. Observera att denna
funktion inte tar bort några nycklar (för det krävs
`gleip_lang_unreg*`).

`gleip_lang_read` läser språkvärden till `lang` från datakällan (se
`gleipnir_lineread`(7)). `buf` och `valid` är frivilliga argument. `buf`
används för att tillfälligt förvara inläst text innan den läggs till i
`lang`; om den är `NULL` så allokeras en buffert av denna funktion och
frigörs innan den returnerar. `valid` sätts för att avgöra om filen är
giltig. Det kan hända att alla giltighetstester inte har utförts om
funktionen returnerar falskt (slut på minne). `lang` rensas automatiskt
innan läsningen av datakällan påbörjas.

Om `valid` är falskt så kan det vara möjligt att avgöra vilken
språknyckel som saknas genom att anropa `gleip_lang_invalid_why`.
Observera dock att denna funktion kan markera en fil som ogiltig av
följande skäl, som inte omfattas av `gleip_lang_invalid_why`:

*	Någon rad innehåller endast en nyckel, men inget värde.
*	Samma nyckel förekommer flera gånger.
*	En nyckel som inte har registrerats påträffades.

Observera att funktionen anropar `gleip_lang_valid` automatiskt som ett
steg i sina giltighetstester. Man behöver alltså inte göra det själv
efter att en fil har lästs in.

En språkfil innehåller två strängar per rad. Den första
mellanslagsavdelade strängen är nyckeln. All följande text på samma rad
betraktas som en enda sammanhängande sträng (mellanslag komprimeras) och
detta är värdet. Exempel:

	key1	Bävrarnas framfart i Europa
	key2	Vad gör bävrarna\
		i Europa?

Efter inläsning kommer detta att resultera i följande hopparningar:

	"key1": "Bävrarnas framfart i Europa"
	"key2": "Vad gör bävrarna i Europa?"

Denna funktion returnerar sant (1) eller falskt (0). Datakällan läses
alltid till slutet (såvida inte inläsningen avbryts av att minnet tar
slut), varför funktionen aldrig returnerar `EOF`. Om `data` är en
`FILE *` så kan man dock anropa `ferror(FILE *)` på den för att kolla om
något har gått fel.

`gleip_lang_read_file` anropar `gleip_lang_read` med en `FILE *` som
datakälla.

`gleip_lang_read_cstr` anropar `gleip_lang_read` med en `const char *`
som datakälla.

`gleip_lang_isreg` kollar om `key` har registrerats i `lang`.

`gleip_lang_regcpy` registrerar `key` i `lang`. `key` kopieras varefter
kopian läggs till i `lang`, så `key` får vara en vanlig C-sträng och
`lang` ansvarar inte för att frigöra den.

*	Nyckeln får inte vara en tom sträng.
*	Nycklar är skiftlägeskänsliga.
*	En och samma nyckel får bara registreras en gång (såvida den
	inte tas bort innan den registreras igen).

`gleip_lang_regref` fungerar som `gleip_lang_regcpy` förutom att `ref`
är en utvidgningsbar C-sträng, och ansvaret att frigöra den överförs
till `lang` (såvida inte funktionen misslyckas).

`gleip_lang_unreg_i` tar bort den registrerade nyckeln som har index
`i`.

`gleip_lang_unreg` tar bort `key`. `key` *måste` ha registrerats (man
kan använda `gleip_lang_isreg` för att avgöra om så är fallet).

`gleip_lang_unreg_all` tar bort alla registrerade nycklar. Om inga
nycklar har registrerats så gör inte funktionen någonting.

`gleip_lang_print` skriver ut alla registrerade nycklar till `out`.
Varje nyckel åtskiljs av `sep`. Funktionen returnerar falskt om det inte
går att skriva ut någon nyckel.

`gleip_lang_cpy` kopierar alla nycklar och värden från `orig` till
`lang`. Alla nycklar i `lang` tas automatiskt bort först. Om funktionen
misslyckas så finns det inga registrerade nycklar i `lang` när
funktionen returnerar. Observera att alla värden kopieras som de är utan
någon hänsyn till om `orig` är giltig. Dessutom görs en fullständig
kopia, så ändringar som senare görs i `lang` reflekteras inte av `orig`.

`gleip_lang_free` frigör en språkpost och allt minne som den ansvarar
för, inklusive alla nycklar som har registrerats med
`gleip_lang_regref`.

`gleip_lang_alloc_mem` allokerar en språkpost med tillräckligt mycket
minne för att rymma `mem` nycklar. Posten kommer naturligtvis att växa
automatiskt om det är nödvändigt.

`gleip_lang_alloc_cpy` allokerar en kopia av `orig` (se `gleip_lang_cpy`
för mer information).

`gleip_lang_alloc` allokerar en språkpost med förvald minneskapacitet
(27).



Returvärde
----------
*	Allokeringsfunktioner (`gleip_lang_alloc*`) returnerar en pekare
	till en språkpost som måste frigöras av anroparen med
	`gleip_lang_free`.
*	Övriga funktioner, som returnerar ett booleskt värde, returnerar
	`true` (1) om åtgärden lyckades och `false` (0) om den
	misslyckades. (1 returneras alltid för `true`.)
*	Hämtningsfunktioner kan returnera `NULL`. I allmänhet gäller att
	hämtningsfunktioner för nycklar aldrig returnerar `NULL` men att
	värden returneras som `NULL` om de inte har lästs in (men
	`gleip_lang_getany` garanterar att returvärdet inte är `NULL`
	genom att returnera nyckeln om värdet saknas).
*	Om en funktion misslyckas så "gör den ingenting", men den kan
	ändra på skräpsträngar som används internt. Inläsningsfunktioner
	som misslyckas 



Exempel
-------
	/*
	 * Feltester har utelämnats.
	 */
	struct gleip_lang	* lang	= ...
	gleip_lang_regcpy	(lang, "key1");
	gleip_lang_regcpy	(lang, "key2");
	FILE			* file	= ...
	gleip_lang_read_file	(lang, file, ...);
	/*
	 * `gleip_lang_get(lang, "key1")` och
	 * `gleip_lang_get(lang, "key2")` är de översatta
	 * språksträngarna.
	 */



Felsökning
----------
Funktioner returnerar falskt (0) om de misslyckas med att allokera
minne. Ingen funktion returnerar `EOF`, men ett I/O-fel kan alltid
uppstå när man ger en `FILE *` som parameter till någon funktion.
Anroparen ansvarar för att anropa `ferror(FILE *)` på filen för att
kolla om ett fel har uppstått.



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



Se även
-------
`gleipnir_line`(7),
`gleipnir_lines`(7),
`gleipnir_lineread`(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.

