⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xml.c

📁 Coware的LISA指令集描述语言开发包
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "xml.h"

#include <stdio.h>
#include <string.h>

/*
	GLOBALS
*/
char  line[INP_MAX_CHAR+1];		// input readed line
int   line_index;				// current char for readed line

// NOTE:
// 'END' keyword or directive is used while searching tags into the array.
// See 'parse' function on identifier match for an example...

// recognized tags
char *tags[] = { "database", "db-dsn", "db-host", "db-name", "db-password", "db-port",
				 "db-type", "db-username", "jdbc", "jdbc-driver", "jdbc-string",
				 "END" };

// db types
char *dbtypes[] = { "mysql", "odbc",
					"END" };

// used for push-back
//	if this ptr not equals NULL, the parse() function will return this value...
lisa_node *pushback_XML_node = NULL;

// this is the XML stream
FILE *xml_stream = NULL;





/*
	FUNCTIONS
*/


// getXMLChar:
//	Get the next char from the xml stream.
//	Return 0 if EOF;
char getXMLChar( void )
{
	char ch;

	// get current char from the line
	ch = line[ line_index ];
	if ( ch == '\0' )
	{
		// empty the previous line...
		line[0] = '\0';
		// ...read a whole line...
		fgets( line, INP_MAX_CHAR, xml_stream );
		// ...and get first char
		line_index = 0;
		ch = line[ line_index ];
	}

	// second '\0' means EOF reached
	if ( ch == '\0' )
	{
		return 0;
	}

	// increase index for next time
	line_index += 1;

	// return current char
	return ch;
}//getXMLChar





// initXMLParser:
//	Initialize the parser.
void initXMLParser( FILE *stream )
{
	// empty pushback buffer...
	if ( pushback_XML_node != NULL )
	{
		destroyNodeR( pushback_XML_node );
		pushback_XML_node = NULL;
	}

	// set the input stream...
	xml_stream = stream;
}//initXMLParser





// parseXML:
//	Parse the xml stream and return a node (token).
//	On error (ie: EOF), return a empty node.
//
//	The SYNTAX is: (pseudo-BNF)
//
//		XML control tag ::= '<?' something '?>'
//		remark          ::= '<!--' anychar '-->'
//		lisa tag        ::= '<' tags '>'
//		                    '</' tags '>'
//		value           ::= { anychar }
lisa_node *parseXML( void )
{
	lisa_node     *node = NULL;
	unsigned char ch;

	// return the push-back node if exists...
	if ( pushback_XML_node != NULL )
	{
		node = pushback_XML_node;
		pushback_XML_node = NULL;
		return node;
	}

	// create a empty node
	node = createNode();

	ch = getXMLChar();

	// ignoring initial blanks...
	while ( strchr( " \t\n\r", ch ) )
	{
		if ( ch == 0 )
		{
			// if no more chars, return a empty node...
			return node;
		}

		// get next char
		ch = getXMLChar();
	}

	switch ( ch )
	{
		case '\0':
		{
			// if no more chars, return a empty node...
			return node;
		}

	// tag ::= '<' anychar... '>'
		case '<':
		{
			int i=0;
			node->element[i] = '\0';
			// search for another char...
			ch = getXMLChar();
			// lowercasing char...
			if ( ch >= 'A' && ch <= 'Z' )
				ch |= 32;

			switch ( ch )
			{
			// XML tag
				case '?':
				{
					// read until '?>'...
					ch = getXMLChar();
					while ( 1 )
					{
						// test for '?'...
						while ( ch != '?' )
						{
							node->element[ i++ ] = ch;
							ch = getXMLChar();
						}
						// test for '>'...
						ch = getXMLChar();
						if ( ch == '>' )
						{
							break;
						}
						else
						{
							node->element[ i++ ] = '?';
							node->element[ i++ ] = ch;
						}
					}
					node->element[ i ] = '\0';
					node->type         = XML_DEFINITION_TAG;
					break;
				}
			// remark tag
				case '!':
				{
					// check for '--'...
					ch = getXMLChar();
					if ( ch != '-' ) error( "bad XML <!-- --> tag" );
					ch = getXMLChar();
					if ( ch != '-' ) error( "bad XML <!-- --> tag" );
					// read until '-->'...
					ch = getXMLChar();
					while ( 1 )
					{
						// test for '-'...
						while ( ch != '-' )
						{
							node->element[ i++ ] = ch;
							ch = getXMLChar();
						}
						// test for '-'...
						ch = getXMLChar();
						if ( ch != '-' )
						{
							node->element[ i++ ] = '-';
							node->element[ i++ ] = ch;
						}
						else
						{
							// test for '>'...
							ch = getXMLChar();
							if ( ch != '>' )
							{
								node->element[ i++ ] = '-';
								node->element[ i++ ] = '-';
								node->element[ i++ ] = ch;
							}
							else
							{
								break;
							}
						}
					}
					node->element[ i ] = '\0';
					node->type         = XML_REMARK_TAG;
					break;
				}
			// end tag
				case '/':
				{
					ch = getXMLChar();
					// lowercasing char...
					if ( ch >= 'A' && ch <= 'Z' )
						ch |= 32;
					while ( strchr( "abcdefghijklmnopqrstuvwxyz_0123456789-", ch ) )
					{
						node->element[i++] = ch;
						ch = getXMLChar();
						if ( ch >= 'A' && ch <= 'Z' )
							ch |= 32;
					}
					node->element[i] = '\0';
					node->type       = XML_LISA_ENDTAG;

					// check for end tag '>' char
					if ( ch != '>' ) error( "bad XML lisa tag" );

					// testing tags match...
					for ( i=0 ; 1 ; i++ )
					{
						char *s = tags[ i ];
						if ( strcmp( s, node->element ) == 0 )
						{
							// founded a valid tag!!!
							node->type = XML_LISA_ENDTAG;
							break;
						}
						if ( strcmp( s, "END" ) == 0 )
						{
							// no tags match...
							error( "unknown XML tag" );
							break;
						}
					}

					break;
				}
			// lisa tag
				case 'a':
				case 'b':
				case 'c':
				case 'd':
				case 'e':
				case 'f':
				case 'g':
				case 'h':
				case 'i':
				case 'j':
				case 'k':
				case 'l':
				case 'm':
				case 'n':
				case 'o':
				case 'p':
				case 'q':
				case 'r':
				case 's':
				case 't':
				case 'u':
				case 'v':
				case 'w':
				case 'x':
				case 'y':
				case 'z':
				{
					// lowercasing char...
					if ( ch >= 'A' && ch <= 'Z' )
						ch |= 32;
					while ( strchr( "abcdefghijklmnopqrstuvwxyz_0123456789-", ch ) )
					{
						node->element[i++] = ch;
						ch = getXMLChar();
						if ( ch >= 'A' && ch <= 'Z' )
							ch |= 32;
					}
					node->element[i] = '\0';
					node->type       = XML_LISA_TAG;

					// check for end tag '>' char
					if ( ch != '>' ) error( "bad XML lisa tag" );

					// testing tags match...
					for ( i=0 ; 1 ; i++ )
					{
						char *s = tags[ i ];
						if ( strcmp( s, node->element ) == 0 )
						{
							// founded a valid tag!!!
							node->type = XML_LISA_TAG;
							break;
						}
						if ( strcmp( s, "END" ) == 0 )
						{
							// no tags match...
							error( "unknown XML tag" );
							break;
						}
					}

					break;
				}
			// BAD TAG DEFINITION!!!
				default:
				{
					error( "bad XML configuration file" );
				}
			}

			break;
		}// case '>'

	// value  ::= { anychar }
		default:
		{
			int i = 0;
			// ignore initials blank spaces...
			while ( strchr( " \t\n\r", ch ) )
				ch = getXMLChar();
			// get the whole value...
			while ( ch != '<' )
			{
				node->element[i++] = ch;
				ch = getXMLChar();
				if ( strchr( "\t\r\n", ch ) ) ch = ' ';
			}
			node->element[i] = '\0';
			node->type       = XML_VALUE;
			// trim endings blank chars...
			if ( i > 0 )
			{
				while ( strchr( " \t\n\r", node->element[ i-1 ] ) )
				{
					node->element[ i-1 ] = '\0';
					i -= 1;
					if ( i == 0 ) break;
				}
			}

			// making a push-back of the '<' char
			pushbackXMLChar();
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -