/*
    This file is part of SUPPL - the supplemental library for DOS
    Copyright (C) 1996-2000 Steffen Kaiser

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: CFGFILE.H 1.1 1999/01/05 01:14:57 ska Exp $
   $Locker:  $	$Name:  $	$State: Exp $

	Declarations for the configuration file & option scanning system

	See CFG.H for more details.

	Notes about the abbreviations:
	* cfgXXX: configuration XXX

*/

#ifndef __CFGFILE_H
#define __CFGFILE_H

#include <portable.h>
#include "supplio.h"

/*********************************
 **** Cfg file types *************
 *********************************/

/*
	CFG_VALTYPE		type of the data of a value
	CFG_ENTRYTYPE	type of the data an entry contains
	cfgf_pos		type of a position within a binfile
	cfgf_fileid		type of a file ID
*/

#ifndef _MICROC_
typedef enum {
		 CFG_TNONE = 0				/* none specified / empty / error */
		,CFG_TSTRING				/* commentable string */
		,CFG_TEXPAND				/* commentable & expandable string */
		,CFG_TBOOLEAN				/* boolean value */
		,CFG_TINTEGER				/* numerical value */
} CFG_VALTYPE;						/* datatype of type of cfgdata */
typedef enum {
		 CFG_EEMPTY = 0				/* empty / unused entry */
		,CFG_EKEY					/* key structure */
		,CFG_EVALUE					/* value structure */
		,CFG_ECONDITION				/* condition structure */
		,CFG_EDATA					/* data structure */
} CFG_ENTRYTYPE;
#else

#define CFG_TNONE		0
#define CFG_TSTRING		1
#define CFG_TEXPAND		2
#define CFG_TBOOLEAN	3
#define CFG_TINTEGER	4
#define CFG_VALTYPE		byte

#define CFG_EEMPTY		0
#define CFG_EDATA		1
#define CFG_EKEY		2
#define CFG_EVALUE		3
#define CFG_ECONDITION	4
#define CFG_ENTRYTYPE	byte
#endif

#ifndef _MICROC_
typedef fpos_t cfgf_pos;
typedef unsigned long cfgf_fileid;
#else
#define cfgf_pos fpos_t
#define cfgf_fileid unsigned
#endif

struct CFGF_Entry_ {			/* binfile entry */
	cfgf_pos cfgf_nxtentry;			/* next entry */
	CFGF_ENTRYTYPE cfgf_entrytype;	/* type of this entry */
	word cfgf_entrylength;			/* length of this entry */
	byte cfgf_data[1];				/* data this entry contains */
};
	
struct CFGF_Key_Entry_ {		/* binfile key */
	cfgf_pos	 cfgf_upkey			/* key this key is a subkey from */
				,cfgf_nxtkey		/* next key of the same upkey */
				,cfgf_prvkey		/* previous key of the same upkey */
				,cfgf_subkeys		/* 1st subkey of this key */
				,cfgf_values		/* 1st value of this key */
				;
	cfgf_fileid	 cfgf_fname;		/* ID of an user cfgfile where any
										modified data is written to */
	char cfgf_keyname[1];			/* name of this key */
};

struct CFGF_Value_Entry_ {		/* binfile value */
	cfgf_pos	 cfgf_key			/* key this value is part of */
				,cfgf_nxtval		/* next value of the same key */
				,cfgf_prvval		/* previous value of the same key */
				,cfgf_conditions	/* 1st condition of this value */
				;
	int cfgf_level;					/* trust level */
	CFG_VALTYPE cfgf_type;			/* data type of this value */
	char cfgf_valname[1];			/* name of this value */
};

struct CFGF_Condition_Entry_ {	/* binfile condition */
	cfgf_pos	 cfgf_value			/* value this condition is part of */
				,cfgf_nxtcnd		/* next condition of the same value */
				,cfgf_prvcnd		/* previous condition of the same value */
				,cfgf_data			/* position of the data */
				;
	char cfgf_cndname[1];			/* name of this value */
};

#ifdef _MICROC_
#define cfgf_ent_t	struct CFGF_Entry_
#define cfgf_keyent_t	struct CFGF_Key_Entry_
#define cfgf_valent_t	struct CFGF_Value_Entry_
#define cfgf_cndent_t	struct CFGF_Condition_Entry_
#else
typedef struct CFGF_Entry_ cfgf_ent_t;
typedef struct CFGF_Key_Entry_ cfgf_keyent_t;
typedef struct CFGF_Value_Entry_ cfgf_valent_t;
typedef struct CFGF_Condition_Entry_ cfgf_cndent_t;
#endif


/*********************************
 **** Cfg file variables *********
 *********************************/

extern const char *cfg_iniSet[];
	/* additional set of INI files to be scanned by the cfgfile subsystem.
		Each entry is inserted into:
			<any_path>\<<entry>>.INI
		usually an entry consists of a filename only.

		The last entry within the array must be NULL.		*/

/*********************************
 **** Cfg file functions *********
 *********************************/

/*
 *	Compare two names of values
 *	Note: Because longname options and value names of configuration
 *	files are the same, this function is also used to compare longname
 *	options.
 *
 *	Return:
 *		 <0: s1 < s2
 *		==0: s1 == s2
 *		 >0: s1 > s2
 */
int cfgEqValue(const char * const s1, const char * const s2);

/*
 * Retreive the type of a value of a key
 *
 *	If key == NULL, the currently selected key is used.
 *
 *	Return:
 *		CFG_K_NONE: on error, e.g. key does not exist
 *		else: type of value
 */
CFG_VALTYPE cfgValType(const char * const key, const char * const value);

/****************************************
 **** Cfg binary file functions *********
 ****************************************/

/*
 * Initialize the cfgfile subsystem
 *
 *	This function will identify the currently active cfgfiles and will
 *	prepare any retreivial function.
 *
 *	If the user wishes to scan more than the default set of INI files,
 *	the <application>.INI and some system-specific ones, the global
 *	variable "char *cfg_iniSet[]" should be defined in the same source file
 *	the call to this function resides in.
 */
void cfgInitFile(void);

/*
 * Shutdown cfgfile subsystem
 *
 *	This function must be called before the process is terminated to
 *	ensure that all allocated resources are freed correctly, e.g. removing
 *	temporary files.
 *
 *	After this function was called no other cfgfile function can be used
 *	successfully, except cfgInitFile() again.
 */
void cfgExitFile(void);

/*
 * Select a key
 *
 *	Make the specified key the "currently selected key".
 *	The key can be given absolutely (beginning with a slash) or relatively
 *	(otherwise).
 *
 *	Return:
 *		0: on success
 *		else: on failure
 */
int cfgSetKey(const char * const key);

/*
 *	Select a section
 *
 *	This is similiar to select the key "/software/<appName>/<section>".
 *
 *	The section name == "" is similiar to not append "/<section>" at
 *	all; section name == NULL is invalid.
 *
 *	Return:
 *		0: on success
 *		else: on failure
 */
int cfgSetSection(const char * const section);


#endif
