From: Andrey C. <sku...@us...> - 2006-06-02 14:14:24
|
Update of /cvsroot/eas-dev/clip-xml In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv4078 Added Files: AUTHORS ChangeLog Makefile.empty Makefile.in TODO _hashxml.h clip-expat.ch clip-expat.h configure expat.c hashxml.h xmltag.prg xmltree.prg xpath.prg Log Message: Add files --- NEW FILE: AUTHORS --- Andrey (Skull) Cherepanov <sk...@ea...> xPath,xmlTree,xmlTag Alena <al...@it...> expat.c --- NEW FILE: ChangeLog --- 2006-16-01 - create xPath, xmlTree 2006-10-01 - create expat.c --- NEW FILE: Makefile.empty --- SSSS = "Warning: package expat-dev not installed" all: echo $(SSSS) install: echo $(SSSS) clean: rm -rf Makefile *.o *.s *.b *.bak *.a *.so *.ex *.nm echo $(SSSS) --- NEW FILE: Makefile.in --- # This is a part of CLIP-XML library # # Copyright (C) 2006 by E/AS Software Foundation # Author: Andrey Cherepanov <sk...@ea...> # # Copyright (C) 2006 by ITK # Author: Alena <al...@it...> # ifndef CLIPROOT CLIPROOT=$(shell cd ../../../; pwd)/cliproot endif include $(CLIPROOT)/include/Makefile.inc CLIPINCLUDE = -I$(CLIPROOT)/include CLIP = $(CLIPROOT)/bin/clip .SUFFIXES: .prg .o .po COMPILER=gcc C_FLAGS=-Wall -g -I. -I$(CLIPROOT)/include -I/usr/include LIBS= -lexpat CC = $(COMPILER) CFLAGS = $(C_FLAGS) XLIB=libclip-xml.a XSLIB=libclip-xml$(DLLSUFF) XSLIBREAL=libclip-xml$(DLLREALSUFF) XTARGETS=$(XLIB) $(XSLIB) SRC = expat.c OBJ = expat.o XLIBOBJS = $(OBJ) OBJS = xmltag.o xmltree.o xpath.o HDRS = clip-expat.ch HASHSRCS = $(SRC) $(HDRS) .PHONY: all clean uninstall distclean all: hash $(SRC) $(OBJS) $(XTARGETS) hash: _hashxml.h _hashxml.h: $(HASHSRCS) $(CLIPROOT)/bin/clip_hashextract $(HASHSRCS) | sort -u > _hashxml.h cmp _hashxml.h hashxml.h 2>/dev/null || cp _hashxml.h hashxml.h $(XLIB): $(XLIBOBJS) $(OBJS) rm -f $(XLIB) $(CLIPROOT)/bin/clip_makelib $(XLIB) $(XLIBOBJS) $(OBJS) ranlib $(XLIB) $(XSLIB): $(XLIB) $(OBJS) $(CLIPROOT)/bin/clip_makeslib $(XSLIB) $(XLIB) $(LIBS) $(OBJS) install: all $(CLIPROOT)/bin/clip_cp $(XLIB) $(XSLIB) $(DESTDIR)$(CLIPROOT)/lib chmod 0644 $(DESTDIR)$(CLIPROOT)/lib/$(XLIB) chmod 0755 $(DESTDIR)$(CLIPROOT)/lib/$(XSLIB) cp clip-expat.ch $(DESTDIR)$(CLIPROOT)/include/ cp clip-expat.h $(DESTDIR)$(CLIPROOT)/include/ mkdir -p $(DESTDIR)$(CLIPROOT)/doc/example/clip-xml cp -R example/* $(DESTDIR)$(CLIPROOT)/doc/example/clip-xml/ clean: cd example && $(MAKE) clean rm -rf Makefile *.o *.s *.b *.bak *.a *.so *.ex *.nm commit: _cvs commit update: _cvs update -dP ucommit: _cvs update -dP && _cvs commit shell: sh .prg.o: $(CLIP) -wn $(CLIPINCLUDE) $< .c.o: @echo $(CC) $(CDBGFLAGS) $(CFLAGS) -c $< @$(CC) $(CDBGFLAGS) $(CFLAGS) $(XCFLAGS) -c $< --- NEW FILE: TODO --- TODO ==== Last change: 18 Apr 2006 - full realization of XPath (attributes, expressions, functions) - SOAP and WSDL - RSS --- NEW FILE: _hashxml.h --- #define HASH_HANDLE 0xD0BA46FC --- NEW FILE: clip-expat.ch --- #define EG_NOPARSER 108 #define XML_PARAM_ENTITY_PARSING_NEVER 0 #define XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE 1 #define XML_PARAM_ENTITY_PARSING_ALWAYS 2 /* Error code */ #define XML_ERROR_NONE 0 #define XML_ERROR_NO_MEMORY 1 #define XML_ERROR_SYNTAX 2 #define XML_ERROR_NO_ELEMENTS 3 #define XML_ERROR_INVALID_TOKEN 4 #define XML_ERROR_UNCLOSED_TOKEN 5 #define XML_ERROR_PARTIAL_CHAR 6 #define XML_ERROR_TAG_MISMATCH 7 #define XML_ERROR_DUPLICATE_ATTRIBUTE 8 #define XML_ERROR_JUNK_AFTER_DOC_ELEMENT 9 #define XML_ERROR_PARAM_ENTITY_REF 10 #define XML_ERROR_UNDEFINED_ENTITY 11 #define XML_ERROR_RECURSIVE_ENTITY_REF 12 #define XML_ERROR_ASYNC_ENTITY 13 #define XML_ERROR_BAD_CHAR_REF 14 #define XML_ERROR_BINARY_ENTITY_REF 15 #define XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF 16 #define XML_ERROR_MISPLACED_XML_PI 17 #define XML_ERROR_UNKNOWN_ENCODING 18 #define XML_ERROR_INCORRECT_ENCODING 19 #define XML_ERROR_UNCLOSED_CDATA_SECTION 20 #define XML_ERROR_EXTERNAL_ENTITY_HANDLING 21 #define XML_ERROR_NOT_STANDALONE 22 #define XML_ERROR_UNEXPECTED_STATE 23 #define XML_ERROR_ENTITY_DECLARED_IN_PE 24 #define XML_ERROR_FEATURE_REQUIRES_XML_DTD 25 #define XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING 26 /* Added in 1.95.7. */ #define XML_ERROR_UNBOUND_PREFIX 27 /* Added in 1.95.8. */ #define XML_ERROR_UNDECLARING_PREFIX 28 #define XML_ERROR_INCOMPLETE_PE 29 #define XML_ERROR_XML_DECL 30 #define XML_ERROR_TEXT_DECL 31 #define XML_ERROR_PUBLICID 32 #define XML_ERROR_SUSPENDED 33 #define XML_ERROR_NOT_SUSPENDED 34 #define XML_ERROR_ABORTED 35 #define XML_ERROR_FINISHED 36 #define XML_ERROR_SUSPEND_PE 37 --- NEW FILE: clip-expat.h --- #ifndef _CLIP_EXPAT_ #define _CLIP_EXPAT_ #include <expat.h> #include <clip.h> #include <error.ch> typedef struct _C_parser C_parser; typedef struct _C_parser { XML_Parser parser; ClipVar obj; ClipMachine *cmachine; ClipVar *userData; int handle; void *data; ClipVar characterDataHandler; /* start function */ ClipVar startElementHandler; /* start function */ ClipVar endElementHandler; /* end function */ ClipVar commentHandler; /* start function */ ClipVar startCdataSectionHandler; /* start function */ ClipVar endCdataSectionHandler; /* end function */ ClipVar defaultHandler; /* start function */ } _C_parser; #define NEW(type) ((type*)calloc(sizeof(type),1)) C_parser *_fetch_c_arg(ClipMachine* cm); C_parser *_register_parser(ClipMachine * cm, XML_Parser parser); C_parser *_list_get_cparser(ClipMachine * cm, void *pointer); void _list_put_cparser(ClipMachine * cm, void *pointer, C_parser * cpar); void _list_remove_cparser(ClipMachine * cm, void * pointer); #define CHECKCPARSER(cpar) \ if(!cpar || !cpar->parser) { \ char err[100]; \ sprintf(err,"No parser object"); \ _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT",EG_NOPARSER,err); \ goto err; \ } #define CHECKARG(n,t) \ if((_clip_parinfo(cm,n)!=t)){ \ char err[100]; \ sprintf(err,"Bad argument (%d), must be a "#t" type",n); \ _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT",EG_ARG,err); \ goto err; \ } #define CHECKARG2(n,t,t2) \ if((_clip_parinfo(cm,n)!=t) && (_clip_parinfo(cm,n)!=t2)){ \ char err[100]; \ sprintf(err,"Bad argument (%d), must be a "#t" or "#t2" type",n); \ _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT",EG_ARG,err); \ goto err; \ } #define CHECKOPT(n,t) \ if((_clip_parinfo(cm,n)!=t)&&(_clip_parinfo(cm,n)!=UNDEF_t)){ \ char err[100]; \ sprintf(err,"Bad argument (%d), must be a "#t" type or NIL",n); \ _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT",EG_ARG,err); \ goto err; \ } #define CHECKOPT2(n,t,t2) \ if((_clip_parinfo(cm,n)!=t)&&(_clip_parinfo(cm,n)!=t2)&&(_clip_parinfo(cm,n)!=UNDEF_t)){ \ char err[100]; \ sprintf(err,"Bad argument (%d), must be a "#t" or "#t2" type or NIL",n); \ _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT",EG_ARG,err); \ goto err; \ } #endif --- NEW FILE: configure --- #!/bin/sh exitf() { rm -f test_expat.c test_expat exit $1 } cp Makefile.empty Makefile cat <<EOF >test_expat.c #include <stdio.h> #include "expat.h" static void startElement(void *userData, const char *name, const char **atts) { } static void endElement(void *userData, const char *name) { } int main(int argc, char *argv[]) { char buf[BUFSIZ]; XML_Parser parser = XML_ParserCreate(NULL); int done; int depth = 0; XML_SetUserData(parser, &depth); XML_SetElementHandler(parser, startElement, endElement); done = XML_STATUS_ERROR; XML_ParserFree(parser); return 0; } EOF EXPAT_EXIST='' gcc -o test_expat test_expat.c -I/usr/include -lexpat >/dev/null 2>&1 && EXPAT_EXIST="yes"] if [ -z $EXPAT_EXIST ] then echo "Warning: package expat-dev not installed or have old version" exitf 1 fi cp Makefile.in Makefile exitf 0 --- NEW FILE: expat.c --- /* Copyright (C) 2005 ITK Author : Kornilova E.V. <al...@it...> License : (GPL) http://www.itk.ru/clipper/license.html */ #include <string.h> #include <errno.h> #include <expat.h> #include "clip.h" #include "screen/charset.h" #include "hashxml.h" #include "clip-expat.h" #include "clip-expat.ch" static ClipVar _xml_list; static ClipVar *xml_list = &_xml_list; CLIP_DLLEXPORT C_parser* _list_get_cparser(ClipMachine * cm, void *pointer) { double d; if (pointer && xml_list->t.type == MAP_t) if (_clip_mgetn(cm, xml_list, (long) pointer, &d) == 0) return (C_parser *) ((long) d); return NULL; } CLIP_DLLEXPORT void _list_put_cparser(ClipMachine * cm, void *pointer, C_parser * cpar) { if (xml_list->t.type != MAP_t) _clip_map(cm, xml_list); if (pointer) _clip_mputn(cm, xml_list, (long) pointer, (long) cpar); } CLIP_DLLEXPORT void _list_remove_cparser(ClipMachine * cm, void * pointer) { if (pointer && xml_list->t.type == MAP_t) _clip_mdel(cm, xml_list, (long) pointer); } CLIP_DLLEXPORT void _destroy_c_parser(void *obj) { C_parser * cpar = (C_parser *)obj; _list_remove_cparser(cpar->cmachine, cpar->parser); _clip_destroy(cpar->cmachine, cpar->userData); _clip_destroy(cpar->cmachine, &cpar->characterDataHandler); _clip_destroy(cpar->cmachine, &cpar->startElementHandler); _clip_destroy(cpar->cmachine, &cpar->endElementHandler); _clip_destroy(cpar->cmachine, &cpar->startCdataSectionHandler); _clip_destroy(cpar->cmachine, &cpar->endCdataSectionHandler); _clip_destroy(cpar->cmachine, &cpar->commentHandler); _clip_destroy(cpar->cmachine, &cpar->defaultHandler); _clip_destroy_c_item(cpar->cmachine, cpar->handle, _C_ITEM_TYPE_XML_PARSER); free(cpar); } CLIP_DLLEXPORT C_parser * _register_parser(ClipMachine * cm, XML_Parser parser) { int handle = -1; C_parser * cpar = (C_parser*)calloc(1,sizeof(C_parser)); cpar->cmachine = cm; cpar->parser = parser; _clip_map(cm, &cpar->obj); /* Saving widget info into CLIP state machine * and it`s handle to a map HANDLE property */ handle = _clip_store_c_item(cm, cpar, _C_ITEM_TYPE_XML_PARSER, NULL); cpar->handle = handle; _clip_mputn(cm, &cpar->obj, HASH_HANDLE, handle); /* Store C_parser pointer in list of parsers */ _list_put_cparser(cm, parser, cpar); return cpar; } CLIP_DLLEXPORT C_parser* _fetch_c_arg(ClipMachine* cm) { C_parser* cpar; if (_clip_parinfo(cm,1)==NUMERIC_t) { cpar = (C_parser*)_clip_fetch_c_item(cm,_clip_parni(cm,1), _C_ITEM_TYPE_XML_PARSER); } else { if (_clip_parinfo(cm,1)==MAP_t) { double h; _clip_mgetn(cm, _clip_spar(cm,1), HASH_HANDLE, &h); cpar = (C_parser *) _clip_fetch_c_item(cm, (int) h, _C_ITEM_TYPE_XML_PARSER); } else { _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT", EG_ARG,"Bad parser descriptor"); return NULL; } } if(!cpar) { _clip_trap_err(cm,EG_ARG,0,0,"CLIP_EXPAT", EG_ARG,"Bad parser descriptor"); return NULL; } return cpar; } static int XMLCALL unknownEncoding(void *encodingHandlerData, const XML_Char *name, XML_Encoding *info) { int i,len1 = 0; cons_CharsetEntry *cs1 = 0; if (load_charset_name((char*) name, &cs1, &len1)) { _clip_logg(2, "translate_charset: cannot load charset file '%s': %s", (char *)name, strerror(errno)); return XML_STATUS_ERROR; } for(i=0; i<256; i++) info->map[i] = i; for (i = 0; i < len1; i++) { int ch; unsigned long unich; cons_CharsetEntry *cp; cp = cs1 + i; ch = cp->ch; unich = cp->unich; if (ch >= 256 || ch<0x80) continue; info->map[i] = unich ; } free(cs1); for (i = 0; i < 32; i++) info->map[i] = i; info->data = 0; info->convert = 0; info->release = 0; return XML_STATUS_OK; } int clip_XML_PARSERCREATE(ClipMachine *cm) { char * encoding = _clip_parc(cm, 1); XML_Parser parser = NULL; C_parser *cpar; CHECKOPT(1,CHARACTER_t); parser = XML_ParserCreate((encoding?encoding:NULL)); XML_SetUnknownEncodingHandler(parser, unknownEncoding, NULL); XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_NEVER); cpar = _register_parser(cm, parser); _clip_mclone(cm,RETPTR(cm),&cpar->obj); return 0; err: return 1; } int clip_XML_PARSERFREE(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); XML_Parser parser = cpar->parser; CHECKCPARSER(cpar); _destroy_c_parser(cpar); XML_ParserFree(parser); return 0; err: return 1; } int clip_XML_SETUSERDATA(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *userData = _clip_par(cm, 2); CHECKCPARSER(cpar); cpar->userData = userData; XML_SetUserData(cpar->parser, cpar); return 0; err: return 1; } int clip_XML_SETPARAMENTITYPARSING(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); int flag = _clip_parni(cm, 2); CHECKCPARSER(cpar); XML_SetParamEntityParsing(cpar->parser, flag); return 0; err: return 1; } int clip_XML_PARSE(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); const char *str = _clip_parc(cm, 2); int len = _clip_parni(cm, 3); int isFinal = _clip_parl(cm, 4); CHECKCPARSER(cpar); CHECKARG(2, CHARACTER_t); CHECKARG(3, NUMERIC_t); CHECKARG(4, LOGICAL_t); _clip_retni(cm, (int)XML_Parse(cpar->parser, str, len, isFinal)); return 0; err: return 1; } int clip_XML_GETERRORCODE(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); CHECKCPARSER(cpar); _clip_retni(cm,XML_GetErrorCode(cpar->parser)); return 0; err: return 1; } int clip_XML_ERRORSTRING(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); CHECKCPARSER(cpar); _clip_retc(cm,(char *) XML_ErrorString(XML_GetErrorCode(cpar->parser))); return 0; err: return 1; } int clip_XML_GETCURRENTLINENUMBER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); CHECKCPARSER(cpar); _clip_retni(cm,XML_GetCurrentLineNumber(cpar->parser)); return 0; err: return 1; } int clip_XML_GETCURRENTCOLUMNNUMBER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); CHECKCPARSER(cpar); _clip_retni(cm,XML_GetCurrentColumnNumber(cpar->parser)); return 0; err: return 1; } static int _character_data_handler(void * userData, const XML_Char * s, int len) { C_parser *cud = (C_parser *)userData; ClipVar str; ClipVar n; ClipVar stack[3], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); memset(&res, 0, sizeof(ClipVar)); memset(&str, 0, sizeof(ClipVar)); memset(&n, 0, sizeof(ClipVar)); _clip_var_str(s, len, &str); n.t.type = NUMERIC_t; n.n.d = len; app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; _clip_mclone(cud->cmachine, &stack[1], &str); _clip_mclone(cud->cmachine, &stack[2], &n); if ( _clip_eval( cud->cmachine, &(cud->characterDataHandler), 3, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); _clip_destroy(cud->cmachine, &stack[1]); _clip_destroy(cud->cmachine, &stack[2]); _clip_destroy(cud->cmachine, &str); _clip_destroy(cud->cmachine, &n); return ret; } int clip_XML_SETCHARACTERDATAHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->characterDataHandler, func); XML_SetCharacterDataHandler(cpar->parser, (XML_CharacterDataHandler)_character_data_handler); return 0; err: return 1; } static int _start_element_handler(void * userData, const XML_Char * name, const XML_Char ** attrs) { C_parser *cud = (C_parser *)userData; ClipVar str; ClipVar *eattr, *item; ClipVar stack[3], *app, *nv = 0; ClipVar res; int ret=1, i, j; unsigned l=0; long vect[2]; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); memset(&str, 0, sizeof(ClipVar)); eattr = malloc(sizeof(ClipVar)); _clip_var_str(name, strlen(name), &str); vect[0] = 0; vect[1] = 0; _clip_array(cud->cmachine, eattr, 1, vect); for(i=0, j=0; attrs[i]; i+=2, j++) { ClipVar var; item = malloc(sizeof(ClipVar)); vect[0] = 2; _clip_array(cud->cmachine, item, 1, vect); vect[0] = j+1; _clip_asize(cud->cmachine, eattr, 1, vect); vect[0] = j; _clip_aset(cud->cmachine, eattr, item, 1, vect); memset(&var, 0, sizeof(var)); var.t.type = CHARACTER_t; var.s.str.buf = (char *)attrs[i]; var.s.str.len = strlen(attrs[i]); vect[1] = 0; _clip_aset(cud->cmachine, eattr, &var, 2, vect); memset(&var, 0, sizeof(var)); var.t.type = CHARACTER_t; var.s.str.buf = (char *)attrs[i+1]; var.s.str.len = strlen(attrs[i+1]); vect[1] = 1; _clip_aset(cud->cmachine, eattr, &var, 2, vect); _clip_destroy(cud->cmachine, item); free(item); } app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; _clip_mclone(cud->cmachine, &stack[1], &str); _clip_mclone(cud->cmachine, &stack[2], eattr); if ( _clip_eval( cud->cmachine, &(cud->startElementHandler), 3, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); _clip_destroy(cud->cmachine, &stack[1]); _clip_destroy(cud->cmachine, &stack[2]); _clip_destroy(cud->cmachine, &str); _clip_destroy(cud->cmachine, eattr); free(eattr); return ret; } int clip_XML_SETSTARTELEMENTHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->startElementHandler, func); XML_SetStartElementHandler(cpar->parser, (XML_StartElementHandler)_start_element_handler); return 0; err: return 1; } static int _end_element_handler(void * userData, const XML_Char * name) { C_parser *cud = (C_parser *)userData; ClipVar str; ClipVar stack[2], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); memset(&str, 0, sizeof(ClipVar)); _clip_var_str(name, strlen(name), &str); app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; _clip_mclone(cud->cmachine, &stack[1], &str); if ( _clip_eval( cud->cmachine, &(cud->endElementHandler), 2, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); _clip_destroy(cud->cmachine, &stack[1]); _clip_destroy(cud->cmachine, &str); return ret; } int clip_XML_SETENDELEMENTHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->endElementHandler, func); XML_SetEndElementHandler(cpar->parser, (XML_EndElementHandler)_end_element_handler); return 0; err: return 1; } int clip_XML_SETELEMENTHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *sfunc = _clip_spar(cm, 2); ClipVar *efunc = _clip_spar(cm, 3); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); CHECKARG2(3, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->startElementHandler, sfunc); _clip_mclone(cm, &cpar->endElementHandler, efunc); XML_SetElementHandler(cpar->parser, (XML_StartElementHandler)_start_element_handler, (XML_EndElementHandler)_end_element_handler); return 0; err: return 1; } static int _comment_handler(void * userData, const XML_Char * data) { C_parser *cud = (C_parser *)userData; ClipVar str; ClipVar stack[2], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); memset(&str, 0, sizeof(ClipVar)); _clip_var_str(data, strlen(data), &str); app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; _clip_mclone(cud->cmachine, &stack[1], &str); if ( _clip_eval( cud->cmachine, &(cud->commentHandler), 2, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); _clip_destroy(cud->cmachine, &stack[1]); _clip_destroy(cud->cmachine, &str); return ret; } int clip_XML_SETCOMMENTHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->commentHandler, func); XML_SetCommentHandler(cpar->parser, (XML_CommentHandler)_comment_handler); return 0; err: return 1; } static int _start_cdata_section_handler(void * userData) { C_parser *cud = (C_parser *)userData; ClipVar stack[1], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; if ( _clip_eval( cud->cmachine, &(cud->startCdataSectionHandler), 1, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); return ret; } int clip_XML_SETSTARTCDATASECTIONHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->startCdataSectionHandler, func); XML_SetStartCdataSectionHandler(cpar->parser, (XML_StartCdataSectionHandler)_start_cdata_section_handler); return 0; err: return 1; } static int _end_cdata_section_handler(void * userData) { C_parser *cud = (C_parser *)userData; ClipVar stack[1], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; if ( _clip_eval( cud->cmachine, &(cud->endCdataSectionHandler), 1, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); return ret; } int clip_XML_SETENDCDATASECTIONHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->endCdataSectionHandler, func); XML_SetEndCdataSectionHandler(cpar->parser, (XML_EndCdataSectionHandler)_end_cdata_section_handler); return 0; err: return 1; } int clip_XML_SETCDATASECTIONHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *sfunc = _clip_spar(cm, 2); ClipVar *efunc = _clip_spar(cm, 3); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); CHECKARG2(3, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->startCdataSectionHandler, sfunc); _clip_mclone(cm, &cpar->endCdataSectionHandler, efunc); XML_SetCdataSectionHandler(cpar->parser, (XML_StartCdataSectionHandler)_start_cdata_section_handler, (XML_EndCdataSectionHandler)_end_cdata_section_handler); return 0; err: return 1; } static int _default_handler(void * userData, const XML_Char * s, int len) { C_parser *cud = (C_parser *)userData; ClipVar str; ClipVar n; ClipVar stack[3], *app, *nv = 0; ClipVar res; int ret=1; unsigned l=0; memset(&stack,0,sizeof(stack)); memset( &res, 0, sizeof(ClipVar) ); memset(&str, 0, sizeof(ClipVar)); memset(&n, 0, sizeof(ClipVar)); _clip_var_str(s, len, &str); n.t.type = NUMERIC_t; n.n.d = len; app = cud->userData; if (!(app->t.flags & F_MREF)) { l =1; nv = NEW(ClipVar); *nv = *app; nv->t.count = 2; app->t.flags = F_MREF /*mptr?F_MPTR:F_MREF */ ; app->p.vp = nv; app->t.field = 0; app->p.fp = 0; } stack[0] = *app; _clip_mclone(cud->cmachine, &stack[1], &str); _clip_mclone(cud->cmachine, &stack[2], &n); if ( _clip_eval( cud->cmachine, &(cud->defaultHandler), 3, stack, &res ) == 0 ) ret = res.t.type == LOGICAL_t ? res.l.val : ret; _clip_destroy(cud->cmachine, &res); if (l) --(nv->t.count); _clip_destroy(cud->cmachine, &stack[1]); _clip_destroy(cud->cmachine, &stack[2]); _clip_destroy(cud->cmachine, &str); _clip_destroy(cud->cmachine, &n); return ret; } int clip_XML_SETDEFAULTHANDLER(ClipMachine *cm) { C_parser *cpar = _fetch_c_arg(cm); ClipVar *func = _clip_spar(cm, 2); CHECKCPARSER(cpar); CHECKARG2(2, PCODE_t, CCODE_t); _clip_mclone(cm, &cpar->defaultHandler, func); XML_SetDefaultHandler(cpar->parser, (XML_DefaultHandler)_default_handler); return 0; err: return 1; } --- NEW FILE: hashxml.h --- #define HASH_HANDLE 0xD0BA46FC --- NEW FILE: xmltag.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-XML library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #define TAGSPACER ' ' /* Base class for XML tag */ function XMLTag( name ) local obj := map() obj:className := "XMLTag" obj:name := name obj:text := "" obj:offset := 0 obj:attributes := array(0) obj:parent := NIL obj:childs := array(0) obj:o := NIL _recover_XMLTAG(obj) return obj function _recover_XMLTAG( obj ) obj:getName := @xml_TagGetName() obj:addChild := @xml_TagAddChild() obj:removeChild := @xml_TagRemoveChild() obj:countChilds := @xml_TagCountChilds() obj:getChild := @xml_TagGetChild() obj:getChilds := @xml_TagGetChilds() obj:setAttribute := @xml_TagSetAttribute() obj:attribute := @xml_TagGetAttribute() obj:getAttributes := @xml_TagGetAttributes() obj:removeAttribute := @xml_TagRemoveAttribute() obj:setText := @xml_TagSetText() obj:getText := @xml_TagGetText() obj:getParent := @xml_TagGetParent() obj:dump := @xml_TagDump() obj:XPath := @xml_TagXPath() return obj /* Get tag name */ static function xml_TagGetName( self ) return self:name /* Add child tag */ static function xml_TagAddChild( self, tag, position ) if valtype(tag) != "O" .or. tag:className != "XMLTag" return .F. endif if empty(position) .or. self:countChilds() < position aadd( self:childs, tag ) else self:childs[ position ] := tag endif tag:parent := self return .T. /* Remove child tag by its number */ static function xml_TagRemoveChild( self, position ) if empty(position) .or. self:countChilds() > position return .F. endif adel( self:childs, position ) asize( self:childs, self:countChilds()-1 ) return .T. /* Number of child tags */ static function xml_TagCountChilds( self ) return len(self:childs) /* Get child tag by its number */ static function xml_TagGetChild( self, position ) if empty(position) .or. self:countChilds() > position return NIL endif return self:childs[ position ] /* Get all childs */ static function xml_TagGetChilds( self ) return self:childs /* Set tag attribute */ static function xml_TagSetAttribute( self, attrName, attrValue ) local p, sValue // Transform attrValue to string switch valtype(attrValue) case 'C' sValue := attrValue case 'N' sValue := ltrim( str( attrValue ) ) case 'L' sValue := iif( attrValue, "true", "false" ) case 'D' sValue := dtoc( attrValue ) otherwise sValue := attrValue endswitch // Lookup attribute name p := ascan( self:attributes, {|e| e[1]==attrName } ) if p == 0 aadd( self:attributes,{ attrName, sValue } ) else self:attributes[ p ] := { attrName, sValue } endif //?? "set attribute", attrName, valtype(sValue), chr(10) return .T. /* Get attribute value */ static function xml_TagGetAttribute( self, attrName, defVal ) local p p := ascan( self:attributes, {|e| e[1]==attrName } ) if p == 0 return defVal endif return self:attributes[p][2] /* Get all attributes */ static function xml_TagGetAttributes( self ) return self:attributes /* Remove tag attribute */ static function xml_TagRemoveAttribute( self, attrName ) local p p := ascan( self:attributes, {|e| e[1]==attrName } ) if p == 0 return .F. endif adel( self:attributes, p ) asize( self:attributes, len(self:attributes)-1 ) return .T. /* Set tag text */ static function xml_TagSetText( self, text ) self:text := text return /* Get tag text */ static function xml_TagGetText( self ) return self:text /* Get parent of tag */ static function xml_TagGetParent( self ) return self:parent /* Dump tag and its childs */ static function xml_TagDump( self, encoding, level ) local indent:='', s:='', a, lastOffset:=1, hasInlineTags:=.F., ct, a2 //?? self:name,chr(10) // Set indentation if empty(level) level := 0 endif if level > 0 indent := replicate(TAGSPACER, level) endif //?? "attrs&\n" // Print tag and attributes s := indent + "<" + self:name + " " //?? self:attributes,chr(10) for a in self:attributes s += a[1] + '="' + xmlText( a[2] ) + '" ' next //?? "childs&\n" if len(self:childs) == 0 if .not. empty(self:text) s := rtrim(s) + ">" + xmlText( self:text ) + "</" + self:name + ">&\n" else s += "/>&\n" endif else s := rtrim(s) + ">" // Look for inline tags (mixed tags and text) for a in self:childs if a:offset > 0 hasInlineTags := .T. exit endif next if hasInlineTags for a in self:childs ct := ltrim( a:dump( encoding, level+1 ) ) ct := left( ct, len(ct)-1 ) if a:offset > 0 s += xmlText( substr( self:text, lastOffset, a:offset-lastOffset+1 ) ) lastOffset := a:offset endif s += ct next s += xmlText( substr(self:text, lastOffset+1 ) ) + "</" + self:name + ">&\n" else s += "&\n" for a in self:childs s += a:dump( encoding, level+1 ) next s += indent + xmlText( self:text ) + "</" + self:name + ">&\n" endif endif return s static function xmlText( text ) text := strtran( text, '&', '&' ) text := strtran( text, '>', '>' ) text := strtran( text, '<', '<' ) text := strtran( text, '"', '"' ) text := strtran( text, "'", ''' ) return text /* Get tag(s) by XPath */ static function xml_TagXPath( self, path ) return xml_XPath( self, path ) --- NEW FILE: xmltree.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-XML library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ #include <clip-expat.ch> #define FILEBLOCK 1024 /* XMLTree class */ function XMLTree( encoding ) local obj := map() obj:className := "XMLTree" obj:encoding := iif( empty(encoding), "utf-8", encoding ) obj:error := "" obj:root := NIL _recover_XMLTREE(obj) return obj function _recover_XMLTREE( obj ) obj:parseFile := @xml_ParseFile() obj:parseString := @xml_ParseString() obj:getRoot := @xml_GetRoot() obj:setRoot := @xml_setRoot() obj:getError := @xml_GetError() obj:XPath := @xml_GetXPath() obj:dump := @xml_Dump() return obj /* Parse XML from file */ static function xml_ParseFile( self, filename ) local parser, file, buf:=space(1024), var, nRead // Create parser parser := xml_ParserCreate() // Set handler functions var:=map() var:ct := NIL var:pt := NIL var:root := NIL xml_SetUserData(parser, @var) xml_SetCharacterDataHandler( parser, @xml_handleText() ) xml_SetElementHandler( parser, @xml_handleElementStart(), @xml_handleElementEnd() ) file = fopen(filename) do while !fileeof(file) nRead := fread(file, @buf, 1024) // Parse buffer xml_Parse(parser, @buf, nRead, fileeof(file)) // Handle buffer if xml_GetErrorCode(parser) <> 0 self:error := xml_ErrorString(parser) + ; " at line "+alltrim( str(xml_GetCurrentLineNumber(parser)) ) + ; ", column "+alltrim( str(xml_GetCurrentColumnNumber(parser)) ) return .F. endif enddo // Close file and free Expat parser self:root := var:root fclose(file) xml_ParserFree(parser) return .T. /* Parse XML from string */ static function xml_ParseString( self, string ) local parser, var // Create parser parser := xml_ParserCreate() // Set handler functions var:=map() var:ct := NIL var:pt := NIL var:root := NIL xml_SetUserData(parser, @var) xml_SetCharacterDataHandler( parser, @xml_handleText() ) xml_SetElementHandler( parser, @xml_handleElementStart(), @xml_handleElementEnd() ) // Parse string xml_Parse(parser, string, len(string), .T.) // Handle buffer if xml_GetErrorCode(parser) <> 0 self:error := xml_ErrorString(parser) + ; " at line "+alltrim( str(xml_GetCurrentLineNumber(parser)) ) + ; ", column "+alltrim( str(xml_GetCurrentColumnNumber(parser)) ) return .F. endif // Free Expat parser self:root := var:root xml_ParserFree(parser) return .T. /* Get root tag */ static function xml_GetRoot( self ) return self:root /* Set XMLTag as root tag */ static function xml_SetRoot( self, tag ) if valtype(tag) != "O" .or. tag:className != "XMLTag" return NIL endif self:root := tag return tag /* Get parse error */ static function xml_GetError( self ) return self:error /* Get tag(s) by XPath */ static function xml_getXPath( self, path, tag ) local t:=NIL if valtype(tag) == "O" .and. tag:className == "XMLTag" t := tag else t := self:root endif return xml_XPath( t, path ) /* Dump tree as XML string */ static function xml_Dump( self, tag ) local t, s, header:="", localEncoding //?? valtype(self:root),chr(10) if valtype(tag) == "O" .and. tag:className == "XMLTag" t := tag elseif .not. empty(self:root) t := self:root header := '<?xml version="1.0" encoding="'+self:encoding+'" ?>'+chr(10)+chr(10) else return "" endif s := self:root:dump() // encode all file: s and self:encoding localEncoding := host_charset() //?? "BEFORE ",self:encoding, localEncoding,":", s, chr(10) if self:encoding != localEncoding s := translate_charset( localEncoding, self:encoding, s) endif //?? "AFTER", s, chr(10) s := header + s return s /**=========================================================================== Handler function for Expat */ /* Handler function for start tag */ function xml_handleElementStart( vUser, name, aAttr ) // Create new XMLTag object //?? "<"+name+">&\n" vUser:ct := XMLTag( name ) vUser:ct:parent := vUser:pt aeval( aAttr, {|e| e[2]:=translate_charset( "utf-8", host_charset(), e[2]) } ) vUser:ct:attributes := aAttr // Append child to parent tag if valtype(vUser:pt) == "O" .and. "CHILDS" $ vUser:pt aadd(vUser:pt:childs, vUser:ct) vUser:ct:offset := len(vUser:pt:text) else vUser:root := vUser:ct endif vUser:pt := vUser:ct return /* Handler function for close tag */ function xml_handleElementEnd( vUser, name ) vUser:pt := vUser:pt:parent vUser:ct := vUser:pt return /* Handler function for text processing */ function xml_handleText( vUser, sStr, nLen ) local s s := translate_charset( "utf-8", host_charset(), alltrim(sStr) ) /* if .not. empty(sStr) ?? "TEXT:", host_charset(), sStr, translate_charset( "utf-8", "koi8-r", alltrim(sStr) ), chr(10) endif */ if .not. empty(s) .and. .not. empty(vUser:ct) vUser:ct:text += s endif return --- NEW FILE: xpath.prg --- /*-------------------------------------------------------------------------*/ /* This is a part of CLIP-XML library */ /* */ /* Copyright (C) 2003-2005 by E/AS Software Foundation */ /* Author: Andrey Cherepanov <sk...@ea...> */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as */ /* published by the Free Software Foundation; either version 2 of the */ /* License, or (at your option) any later version. */ /*-------------------------------------------------------------------------*/ /* This function support Xpath by following version: XML Path Language (XPath) Version 1.0 W3C Recommendation 16 November 1999 [...1043 lines suppressed...] childs := b:childs otherwise s := '[UNKNOWN]' if 'TOKEN' $ b switch valtype( b:token ) case 'C' s := '"' + b:token + '"' case 'N' s := alltrim( str( b:token ) ) case 'L' s := iif( b:token, '.T.', '.F.' ) endswitch endif endswitch ?? l + s + chr( 10 ) for cN in childs _xpath_dumpBlock( cN, level + 1 ) next return NIL |