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



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



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



Argument
--------

`dst`
:	Pekare till strängen som alla tecken kopieras till. Detta måste
	vara en utvidgningsbar C-sträng.

`lines`
:	Bufferten som alla rader läggs till i. När text delas upp så
	läggs varje del till som en sträng i denna buffert.

`data`
:	Datakällan. `callback_data_next` läser tecken från datakällan.
	Detta kan exempelvis vara en `FILE *` eller en vanlig C-sträng.

`src`
:	En pekare till en vanlig C-sträng. C-strängen får vara i
	skrivskyddat minne. Pekaren ökar medan den itererar över `src`,
	så `(* src)[0]` kommer att vara `'\0'` när `callback_data_next`
	returnerar `EOF` (när hela strängen har lästs in).

`callback_data_next`
:	Denna funktion läser nästa `int` från `data`. Detta är antingen
	en `char` eller `EOF`. `EOF` är antingen slutet på datakällan
	eller ett I/O-fel (vilket man kan avgöra med `ferror(FILE *)` om
	`data` är en `FILE *`). Om `data` är en `FILE *` så kan denna
	funktion vara `fgetc(FILE *)`.

`callback_tkn_delim`
:	Detta valfria argument är en funktionspekare som avgör om en
	inläst `char` är en ordavdelare. Funktionen kan exempelvis vara
	`isspace(int)`. Om den är `NULL` så delas inte orden upp.

`callback_line_delim`
:	Detta valfria argument är en funktionspekare som avgör om en
	inläst `char` är ett radbrytningstecken. Om så är fallet så
	slutar funktionen omedelbart läsa från datakällan och returnerar
	när en sådan `char` påträffas. Om en `char` är både en
	ordavdelare och ett radbrytningstecken så väger radbrytningen
	tyngre. Om denna funktionspekare är `NULL` så returnerar inte
	funktionen när nya rader påträffas.

`tkns_max`
:	Det största antalet strängar som läggs till i `lines`. Om värdet
	är 0 så finns det ingen begränsning.

`condense_sym`
:	När fler ord inte kan läggas till på grund av `tkns_max` så
	komprimeras alla ordavdelande tecken till en enda
	`condense_sym`. Om `callback_tkn_delim` är `isspace(int)` så är
	detta tecken ofta ett mellanslag. Får inte vara `'\0'`.



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

Följande symboler har deklarerats med `#define` så att man kan använda
`switch` på dem:

*	`GLEIP_LINEREAD_COMMENT` är kommentarstecknet (`#`).
*	`GLEIP_LINEREAD_ESCAPE` är tolkningstecknet (`\`).
*	`GLEIP_LINEREAD_QUOTED` är det dubbla citationstecknet (`"`).
*	`GLEIP_LINEREAD_QUOTES` är det enkla citationstecknet (`'`).

`gleip_lineread_raw` är den grundläggande radläsningsfunktionen som inte
tolkar några tecken (alla tecken läggs alltså till som de är utan någon
speciell hantering). Man kan dela upp den inlästa texten i ord genom att
ge en `callback_tkn_delim`-parameter som inte är `NULL` (exempelvis
`isspace(int)` eller en funktion som returnerar sant för `'\n'`), men
det är valfritt.

`data` läses en `char` åt gången av `callback_data_next` tills
`callback_tkn_delim` returnerar sant, då funktionen returnerar. Tecknet
som avskiljer orden från varandra läggs *inte* till i den
utvidgningsbara C-strängen som `dst` pekar på. Funktionen returnerar
också när `callback_data_next` returnerar `EOF`, vilket sker antingen
när `data` tar slut eller (om `data` är en `FILE *`) vid ett I/O-fel.
`dst` rensas inte automatiskt; om den inte är tom så läggs de nya
tecknen till på slutet av strängen.

Denna funktion kan returnera `EOF` (ett sant booleskt värde) vid
datakällans slut (eller ett I/O-fel), falskt om den misslyckas med att
allokera minne eller sant om allt lyckades. Observera att `EOF` är ett
negativt värde som inte är 0, så `EOF` är alltså ett sant booleskt
värde. Om `data` är en `FILE *` så kan man använda `ferror(FILE *)` för
att skilja på datakällans slut och I/O-fel.

`gleip_lineread_raw_eof` liknar `gleip_lineread_raw` förutom att den
läser hela datakällan tills `EOF` returneras. Om datakällan är en
`FILE *` så läser den antingen hela filen eller så mycket den kan tills
ett I/O-fel påträffas eller minnet tar slut. En annan skillnad är att
`gleip_lineread_raw_eof` aldrig returnerar `EOF` (det skulle ju vara
meningslöst eftersom den alltid läser till slutet på datakällan). De
uppdelade orden läggs till som utvidgningsbara C-strängar i `lines`.
`lines` rensas *inte* automatiskt innan inläsningen påbörjas, och om den
inte är tom så läggs strängarna till sist i bufferten.

Alla andra `gleip_lineread_raw*`-funktioner delegerar de ovan nämnda
funktionerna med lämpliga parametrar för att läsa från `FILE` och
vanliga C-strängar.

`gleip_lineread_raw_file` anropar `gleip_lineread_raw` med en `FILE *`
som datakälla.

`gleip_lineread_raw_file_nl` anropar `gleip_lineread_raw_file` och delar
upp ord vid radbrytningstecken (`'\n'`).

`gleip_lineread_cb_data_next_cstr` kan ges som parameter till
`callback_data_next` om datakällan är en `const char * *` (pekare till
en vanlig C-sträng). Denna funktion ökar pekaren (`src`) och returnerar
`EOF` när `'\0'` påträffas. Observera att detta medför att C-strängen
som `src` pekar på kommer att öka tills den innehåller en sträng med
längd 0 (`(* src)[0]` är `'\0'`), så det kan vara en bra idé att behålla
en kopia av den ursprungliga pekaren när denna funktion anropas (liksom
man kan anropa `fseek()` på en `FILE` för att spola tillbaka den).

`gleip_lineread_raw_cstr` anropar `gleip_lineread_raw` med en
`const char *` som datakälla (`src`). Observera att C-strängen som `src`
pekar på kommer att öka som ovan.

`gleip_lineread_raw_cstr_nl` anropar `gleip_lineread_raw_cstr` och delar
upp ord vid radbrytningstecken (`'\n'`).

`gleip_lineread_raw_eof_file` anropar `gleip_lineread_raw_eof` med en
`FILE *` som datakälla.

`gleip_lineread_raw_eof_file_nl` anropar `gleip_lineread_raw_eof_file`
och delar upp ord vid radbrytningstecken (`'\n'`).

`gleip_lineread_raw_eof_cstr` anropar `gleip_lineread_raw_eof` med en
`const char *` som datakälla (`src`). Observera att C-strängen som `src`
pekar på kommer att öka som ovan.

`gleip_lineread_raw_eof_cstr_nl` anropar `gleip_lineread_raw_eof_cstr`
och delar upp ord vid radbrytningstecken (`'\n'`).

`gleip_lineread_interp` är den grundläggande radläsningsfunktionen som
tolkar specialtecken. Denna funktion skiljer på *ord* och *rader*. Ord
läggs till som utvidgningsbara C-strängar i `lines` tills ett tolkat
radbrytningstecken påträffas, då funktionen returnerar. `lines` rensas
inte automatiskt innan inläsningen påbörjas, men man måste göra det om
`tkns_max > 0` (det är dock valfritt om `tkns_max = 0`). Liksom
`gleip_lineread_raw` returnerar denna funktion `EOF` vid datakällans
slut (eller I/O-fel).

*	`callback_tkn_delim` avskiljer varje C-sträng som läggs till i
	`lines`. Tecknen som avskiljer strängarna läggs inte till i
	`lines`. Om funktionspekaren är `NULL` så delas inte orden upp.
	-	Om inga fler ord får läggas till som separata strängar
		(på grund av `tkns_max`) så komprimeras flera på
		varandra följande ordavdelningstecken till en enda
		`condense_sym`.
	-	Om ordavdelningstecken föregås av `\`, eller är inom
		enkla eller dubbla citationstecken, så läggs de till som
		de är utan att texten delas upp i ord eller komprimeras
		till en `condense_sym`.
	-	`tkns_max` bestämmer hur många ord som får läggas till i
		`lines` som mest. 0 innebär att det inte finns någon
		begränsning.
*	`callback_line_delim` avgör när funktionen ska returnera. Om den
	är `NULL` så returnerar funktionen först när datakällan
	returnerar `EOF`. Radbrytningstecknet läggs inte till i `lines`.
	-	Om ett radbrytningstecken föregås av `\` så hoppas det
		över och funktionen fortsätter läsa på nästa rad.
	-	Om `callback_tkn_delim` returnerar sant för samma `char`
		så väger `callback_line_delim` tyngre.

Följande tecken kan tolkas, utöver rad- och ordavdelningstecken:

*	`GLEIP_LINEREAD_COMMENT` (`#`) gör så att resten av raden
	ignoreras. Ett radbrytningstecken är tecknet som gör att
	`callback_line_delim` returnerar sant. Om `callback_line_delim`
	är `NULL` så gör ett kommentarstecken så att funktionen
	fortsätter läsa `data` till `EOF`. Annars läses `data` till
	nästa radbrytningstecken, varpå funktionen returnerar.
*	`GLEIP_LINEREAD_ESCAPE` (`\`) kan föregå ett radbrytningstecken
	för att det ska ignoreras, eller en tolkad symbol för att det
	ska läggas till utan att tolkas. Det kan dessutom användas för
	att infoga följande kontrolltecken från C:
	-	`'\a'`
	-	`'\b'`
	-	`'\f'`
	-	`'\n'`
	-	`'\r'`
	-	`'\t'`
	-	`'\v'`
*	`GLEIP_LINEREAD_QUOTED` (`"`) gör så att alla tecken utom dubbla
	citationstecken och tolkningssymbolen läggs till utan att
	tolkas. Det gör också så att radbrytnings- och
	ordavdelningstecken läggs till utan att tolkas.
*	`GLEIP_LINEREAD_QUOTED` (`"`) gör så att alla tecken utom enkla
	citationstecken läggs till utan att tolkas. Det gör också så att
	radbrytnings- och ordavdelningstecken läggs till utan att
	tolkas.

Alla andra `gleip_lineread_interp*`-funktioner delegerar de ovan nämnda
funktionerna med lämpliga parametrar för att läsa från `FILE` och
vanliga C-strängar.

`gleip_lineread_interp_def` anropar `gleip_lineread_interp` med förvalda
ordavdelnings- och radbrytningstecken. Dessa är `isspace(int)` och en
funktion som returnerar sant för `'\n'`. `condense_sym` är ett
mellanslag.

`gleip_lineread_interp_file` anropar `gleip_lineread_interp` med en
`FILE *` som datakälla.

`gleip_lineread_interp_file_def` anropar `gleip_lineread_interp_file`
med förvalda ordavdelnings- och radbrytningstecken, som 
`gleip_lineread_interp_def`.

`gleip_lineread_interp_cstr` anropar `gleip_lineread_interp` med en
`const char *` som datakälla (`src`). Observera att C-strängen som `src`
pekar på kommer att öka som ovan.

`gleip_lineread_interp_cstr_def` anropar `gleip_lineread_interp_cstr`
med förvalda ordavdelnings- och radbrytningstecken, som 
`gleip_lineread_interp_def`.



Returvärde
----------
*	Vissa funktioner returnerar `EOF` för att markera slutet på
	datakällan. Detta kan även bero på ett I/O-fel om datakällan är
	en `FILE *`.
	-	Observera att detta kan kombineras med ett booleskt
		returvärde eftersom falskt definieras som 0, sant som
		inte 0, och `EOF` som ett negativt tal. Således kommer
		`EOF` alltid att vara booleskt sant.
*	Alla funktioner 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`; detta garanteras
	i synnerhet när ett booleskt värde kan vara `EOF`.)
*	Om en inläsningsfunktion misslyckas så kan det hända att endast
	en del av filen har lästs in.



Exempel
-------
	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;



Felsökning
----------
Funktioner returnerar falskt (0) om de misslyckas med att allokera
minne. Vissa funktioner returnerar `EOF`, vilket kan vara ett I/O-fel om
datakällan är en `FILE *`. 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_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.

