#ifndef _SUBSTI_H_INCLUDED



/*
 * Ze ZADANYCH radku textu je vytvaren seznam dvojic symbol+hodnota.
 * Ten je nasledne APLIKOVAN pro prislusnou substituci.
 * Zadani:   "$$SYMBOL 173"                            - prirazeni $SYMBOL=173.
 * Aplikace: "Nad lesem leti $SYMBOL vran!"            - nahrada $SYMBOL-->173.
 * Vystup:   "Nad lesem leti 173 vran!"
 * Samozrejme je nutne dodrzet poradi: 1.zadani, 2.aplikace.
 * Zadani samotneho symbolu (radek textu nepokracuje hodnotou) zpusbi vyrazeni
 * clanku s odpovidajicim symbolem ze seznamu.
 *
 * Ciselne hodnoty zastoupene symboly, na jejichz absolutni hodnote nezalezi
 * (postaci, kdyz se vzajemne lisi), mohou byt generovany automaticky.
 * Zadani:   "$$BASE. 11"                              - novy "bazovy symbol".
 * Aplikace: "$BASE.ALFA, $BASE.BETA, $BASE.GAMA"      - vytvoreni posloupnosti
 * Vystup:   "11, 12, 13"
 * POZOR: Symboly s bazovym symbolem (viz. "$BASE.ALFA", ...) se neobjevi
 *        ve forme ZADANI (tedy "$$BASE.ALFA"), vzdy jen jako APLIKACE!
 *
 * Pokud musi v textu symbolem v aplikaci nasledovat znak '.' je treba odlisit
 * ho od automatickeho generovani.
 * Zadani:   "$$KOLIK_NAS_BYLO pet"                    - prirazeni
 * Aplikace: "Bylo nas $(KOLIK_NAS_BYLO)."             - nahrada
 * Vystup:   "Bylo nas pet."
 */


// Specialni znaky pouzite v textu
//
#define  SUBSTI_CHRS_SYMBOL		'$'		// symbol
#define  SUBSTI_CHRS_COMMENT	'#'		// komentar (do konce radku)
#define  SUBSTI_CHRS_BASE		'.'		// oddelovac "bazoveho symbolu"
#define  SUBSTI_CHRS_LBKT		'('		// zavorky kolem...
#define  SUBSTI_CHRS_RBKT		')'		// ...symbolu


#ifdef __cplusplus
extern "C" {
#endif



// Handle
//
struct substis;
//
typedef struct substis	*substihndp_t;


// Typy pointeru na funkce pro spravu pameti
//
typedef void			*(*substiallocfncp_t)(unsigned);
typedef void			(*substifreefncp_t)(void *);


// Inicializace - prvotni alokace pameti
//
extern substihndp_t		substi_initial0(substiallocfncp_t,
										substifreefncp_t,
										int __symbolc,
										int __commentc);
/*
vstup:
  substiallocfncp_t:	Pointer na funkci prideleni pameti.
  substifreefncp_t:		Pointer na funkci uvolneni pameti.
  __symbolc:			Znak uvozujici symbol.
  __commentc:			Znak uvozujici komentar.

  vraci:				"Handle", nebo NULL pri chybe alokovani pameti.
 */


// Makra pro nejcastejsi pouziti inicializacni funkce
//
#define  substi_initial()													\
		 substi_initial0(malloc, free, SUBSTI_CHRS_SYMBOL, SUBSTI_CHRS_COMMENT)
//
#define  substi_initial_mem(a, f)											\
		 substi_initial0((a),    (f),  SUBSTI_CHRS_SYMBOL, SUBSTI_CHRS_COMMENT)
//
#define  substi_initial_chrs(s, c)											\
		 substi_initial0(malloc, free, (s), (c))
/*
extern substihndp_t		substi_initial();
extern substihndp_t		substi_initial_mem(substiallocfncp_t,
										   substifreefncp_t);
extern substihndp_t		substi_initial_chrs(int __symbolc,
											int __commentc);
 */


// Zpracovani jednoho radku textu
//
extern char const		*substi_operate(substihndp_t,
										char const *__linep);
/*
vstup:
  substihndp_t:			"Handle" (to, co vrati funkce "substi_initial()").
  __linep:				Pointer na radek textu pro upravu.

  vraci:				Pointer na radek textu po uprave,
						nebo NULL pri chybe alokovani pameti.
 */


// Uvolneni naalokovane pameti
//
extern void				substi_leave(substihndp_t);
/*
vstup:
  substihndp_t:			"Handle" (to, co vrati funkce "substi_initial0()").
 */


// Typy pointeru na callback-funkci seznamu dvojic pro ladeni
//
#define  SUBSTI_LIST_CONTINUE	0		// pokracovat...
#define  SUBSTI_LIST_BREAK		1		// ...nebo zastavit prochazeni seznamu
//
typedef int				(*substilistfncp_t)(char const *__symp,
											char const *__valp,
											void       *__userdata);
/*
vstup:
  __symp:				"Symbol".
  __valp:				"Hodnota".
  __userdata:			Uzivatelska data.

  vraci:				"SUBSTI_LIST_CONTINUE" nebo "SUBSTI_LIST_BREAK".
 */


// Pro ladeni: seznam dvojic symbol+hodnota.
//
#define  SUBSTI_LIST_ERROR		(-1)	// chyba pri alokovani pameti
//
extern int				substi_list(substihndp_t,
									substilistfncp_t,
									void *__userdata);
/*
vstup:
  substihndp_t:			"Handle" (to, co vrati funkce "substi_initial()").
  substilistfncp_t:		Pointer na callback-funkci.
  __userdata:			Uzivatelska data pro callback-funkci.

  vraci:				Neco ze sortimentu "SUBSTI_LIST_*".
 */



#ifdef __cplusplus
}
#endif



#define _SUBSTI_H_INCLUDED
#endif
