/*
 *  xml.h
 *
 *    Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
 */

#ifndef __xml_h
#define __xml_h

#ifdef KERNEL
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/ctype.h>

#define PRINTF          printk
#define MALLOC(x)       ( void* )kmalloc( x, GFP_ATOMIC )
#define FREE(x)         kfree(x)
#else
#include <stdlib.h>
#define PRINTF          printf
#define MALLOC(x)       ( void* )malloc( x )
#define FREE(x)         free(x)
#define ld_panic(x)     { printf( x ); exit(1);}
#endif


typedef struct xml_node_t{
        int     iTagType;               /* XML_TAGTYPE_xxx #defines will be available */
        char    *pszTag;                /* contains the tag, usefull for unknown/undefined entities */
        int     iNumAttr;               /* number of attributes for this entity */
        char    **ppszAttrName;         /* the attributes names */
        char    **ppszAttrValue;        /* the attribute values */
        int     iNumChild;              /* number of children */
        struct  xml_node_t **ppChild;   /* ordered array of pointers to children*/
	struct  xml_node_t *pParent;	/* pointer to the parent node or NULL if root */
        char    *pszBody;               /* body of the entity, if leaf; otherwise the body w/o the sub-entities */
	int	iLineNumber;		/* line number in the xml string */
}xml_node_t;

typedef struct{
	xml_node_t	*pxnRoot;	/* the root node of the element tree */
	char		*pszXmlVersion;	/* contains the version from the <?xml ...?>-tag */
	char		*pszXmlEncoding;/* dito for the encoding */
	char		*pszDocType;	/* the value from the <?DOCTYPE....?>-tag */
}xml_doc_t;

#define XML_TAGTYPE_UNKNOWN			0
/* this is not a real tag, but a container for text in non-leaf tags */
#define XML_TAGTYPE_LEAF			1

#define XML_TAGTYPE_eServer_ipl_script		2
#define XML_TAGTYPE_type			3
#define XML_TAGTYPE_start			4
#define XML_TAGTYPE_ipl_control_section		5
#define XML_TAGTYPE_ipl_platform_loader		6
#define XML_TAGTYPE_fcp_ipl			7
#define XML_TAGTYPE_devno			8
#define XML_TAGTYPE_wwpn			9
#define XML_TAGTYPE_did				10
#define XML_TAGTYPE_fcp_lun			11
#define XML_TAGTYPE_mbr_lba			12
#define XML_TAGTYPE_configuration		13
#define XML_TAGTYPE_system_control_program	14
#define XML_TAGTYPE_parameter_string		15
#define XML_TAGTYPE_cssid			17
#define XML_TAGTYPE_file_name			18
#define XML_TAGTYPE_scp_loader			19
#define XML_TAGTYPE_dump_control_section	20
#define XML_TAGTYPE_dump_platform_loader	21
#define XML_TAGTYPE_fcp_dump			22
#define XML_TAGTYPE_timeout			24

/* verification errors */
#define XML_VE_TOPLEVEL_TOOMANY						-2
#define XML_VE_TOPLEVEL_INVTAG						-3

#define XML_VE_eServer_ipl_script_INVTAG				-4

#define XML_VE_dump_control_section_INVTAG				-5
#define XML_VE_dump_control_section_TOOMANY_dump_platform_loader	-6
#define XML_VE_dump_control_section_NO_dump_platform_loader		-7

#define XML_VE_ipl_control_section_INVTAG				-8
#define XML_VE_ipl_control_section_TOOMANY_ipl_platform_loader		-9
#define XML_VE_ipl_control_section_NO_ipl_platform_loader		-10
#define XML_VE_ipl_control_section_TOOMANY_system_control_program	-11

#define XML_VE_system_control_program_INVTAG				-12
#define XML_VE_system_control_program_TOOMANY_parameter_string		-13
#define XML_VE_system_control_program_TOOMANY_scp_loader		-14

#define XML_VE_dump_platform_loader_INVTAG				-15
#define XML_VE_dump_platform_loader_N_dump_N_fcp_dump			-16
#define XML_VE_dump_platform_loader_TOOMANY_dump_ANDOR_fcp_dump		-17

#define XML_VE_ipl_platform_loader_INVTAG				-18
#define XML_VE_ipl_platform_loader_N_ipl_N_fcp_ipl			-19
#define XML_VE_ipl_platform_loader_TOOMANY_ipl_ANDOR_fcp_ipl		-20

#define XML_VE_fcp_dump_INVTAG						-27
#define XML_VE_fcp_dump_TOOMANY_cssid					-28
#define XML_VE_fcp_dump_TOOMANY_devno					-29
#define XML_VE_fcp_dump_NO_devno					-30
#define XML_VE_fcp_dump_TOOMANY_wwpn					-31
#define XML_VE_fcp_dump_TOOMANY_did					-32
#define XML_VE_fcp_dump_TOOMANY_fcp_lun					-33
#define XML_VE_fcp_dump_NO_fcp_lun					-34
#define XML_VE_fcp_dump_TOOMANY_configuration				-35
#define XML_VE_fcp_dump_TOOMANY_file_name				-36
#define XML_VE_fcp_dump_N_wwpn_N_did					-37
#define XML_VE_fcp_dump_TOOMANY_wwpn_ANDOR_did				-38

#define XML_VE_fcp_ipl_INVTAG						-48
#define XML_VE_fcp_ipl_TOOMANY_cssid					-49
#define XML_VE_fcp_ipl_TOOMANY_devno					-50
#define XML_VE_fcp_ipl_NO_devno						-51
#define XML_VE_fcp_ipl_TOOMANY_wwpn					-52
#define XML_VE_fcp_ipl_TOOMANY_did					-53
#define XML_VE_fcp_ipl_TOOMANY_fcp_lun					-54
#define XML_VE_fcp_ipl_TOOMANY_configuration				-55
#define XML_VE_fcp_ipl_TOOMANY_file_name				-56
#define XML_VE_fcp_ipl_TOOMANY_mbr_lba					-57
#define XML_VE_fcp_ipl_N_wwpn_N_did					-58
#define XML_VE_fcp_ipl_N_file_name_N_mbr_lba				-59

/* #define XML_VE_dump_control_section_INVTAG				-60 	aka -5 */
#define XML_VE_dump_control_section_TOOMANY_system_control_program	-61
#define XML_VE_dump_control_section_TOOMANY_scp_loader			-62
#define XML_VE_dump_control_section_TOOMANY_parameter_string		-63

#define XML_VE_eServer_ipl_script_TOOMANY_type				-64
#define XML_VE_eServer_ipl_script_TOOMANY_start				-65
#define XML_VE_eServer_ipl_script_NO_type				-66
#define XML_VE_eServer_ipl_script_TOOMANY_timeout			-67

#define XML_VE_INVALID_HEX_VALUE					-101

/* messages */
/* PLAN: move these to common (ldipl) message file ?! */

typedef struct{
	int	iMsgNo;							/* message number */
	void	**ppvInsert;						/* array of pointers to the inserts */
}xml_msg_t;

extern	char	*xml_message[ ];

#define	XML_MESSAGE(MSGNO)	{							\
					xml_msg_t	xm;					\
					xm.iMsgNo = MSGNO;					\
					xml_msgOutput( &xm );					\
					}


#define	XML_MESSAGE_SD(MSGNO, S, D)	{							\
					xml_msg_t	xm;					\
					int		i=D;					\
					xm.iMsgNo = MSGNO;					\
					xm.ppvInsert = ( void** )MALLOC( 2*sizeof( void* ) );	\
					xm.ppvInsert[ 0 ] = S;					\
					xm.ppvInsert[ 1 ] = &i;					\
					xml_msgOutput( &xm );					\
					}
#define XML_MESSAGE_D(MSGNO, D)		{                                                       \
					xml_msg_t       xm;                                     \
					int             i=D;                                    \
					xm.iMsgNo = MSGNO;                                      \
					xm.ppvInsert = ( void** )MALLOC( 1*sizeof( void* ) );   \
					xm.ppvInsert[ 0 ] = &i;                                 \
					xml_msgOutput( &xm );                                   \
					}

#define	XML_MESSAGE_SS(MSGNO, S, S2)	{							\
					xml_msg_t	xm;					\
					xm.iMsgNo = MSGNO;					\
					xm.ppvInsert = ( void** )MALLOC( 2*sizeof( void* ) );	\
					xm.ppvInsert[ 0 ] = S;					\
					xm.ppvInsert[ 1 ] = S2;					\
					xml_msgOutput( &xm );					\
					}


/* protoypes */
void xml_msgOutput( xml_msg_t *pxm );

/* xml parser functions - should be the only functions used externally */
int		xml_parse( char *pXmlDoc, xml_doc_t **ppxd );


/* string functions, be carefull when using these, their semantic might have been slightly adapted */
char		*xml_strdup( char *psz );
int		xml_strcmp( char *psz1, char *psz2 );
int		xml_strlen( char *psz );

int		xml_isHex( char *psz, int iMin, int iMax, int iClean );

/* helper functions */
int		xml_getNextLine( char *pLine, int iSize, char **ppPos );
int		xml_checkTag( char *pszLine, char *pszTag, char *pszAttr );

void		xml_die( void );
int		xml_verify( xml_doc_t *pxd );

/* xml_node functions */
xml_node_t	*xml_nodeNew( xml_node_t *pnParent );
int		xml_nodeAddChild( xml_node_t *pnParent, xml_node_t *pnChild );
int		xml_nodeAddAttr( xml_node_t *pn, char *pszName, char *pszValue );
int		xml_nodeAddAttrFromString( xml_node_t *pn, char *pszAttr );
int		xml_nodeAppendToBody( xml_node_t *pxn, char *psz );

/* xml_doc functions */
xml_doc_t	*xml_docNew( void );

#endif
