609 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			609 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*  $Id$
 | ||
|  | 
 | ||
|  |     Part of SWI-Prolog | ||
|  | 
 | ||
|  |     Author:        Jan Wielemaker | ||
|  |     E-mail:        J.Wielemaker@cs.vu.nl | ||
|  |     WWW:           http://www.swi-prolog.org
 | ||
|  |     Copyright (C): 1985-2009, VU University Amsterdam | ||
|  | 
 | ||
|  |     This library is free software; you can redistribute it and/or | ||
|  |     modify it under the terms of the GNU Lesser General Public | ||
|  |     License as published by the Free Software Foundation; either | ||
|  |     version 2.1 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 | ||
|  |     Lesser General Public License for more details. | ||
|  | 
 | ||
|  |     You should have received a copy of the GNU Lesser General Public | ||
|  |     License along with this library; if not, write to the Free Software | ||
|  |     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | ||
|  | */ | ||
|  | 
 | ||
|  | #include <SWI-Stream.h>
 | ||
|  | #include <SWI-Prolog.h>
 | ||
|  | #include <string.h>
 | ||
|  | #ifdef __WINDOWS__
 | ||
|  | #define inline __inline
 | ||
|  | #endif
 | ||
|  | 
 | ||
|  | #include "turtle_chars.c"
 | ||
|  | 
 | ||
|  | 		 /*******************************
 | ||
|  | 		 *	       ERRORS		* | ||
|  | 		 *******************************/ | ||
|  | 
 | ||
|  | static atom_t	 ATOM_; | ||
|  | static functor_t FUNCTOR_error2; | ||
|  | static functor_t FUNCTOR_type_error2; | ||
|  | static functor_t FUNCTOR_syntax_error1; | ||
|  | static functor_t FUNCTOR_representation_error1; | ||
|  | 
 | ||
|  | static int | ||
|  | type_error(term_t actual, const char *expected) | ||
|  | { term_t ex; | ||
|  | 
 | ||
|  |   if ( (ex = PL_new_term_ref()) && | ||
|  |        PL_unify_term(ex, | ||
|  | 		     PL_FUNCTOR, FUNCTOR_error2, | ||
|  | 		       PL_FUNCTOR, FUNCTOR_type_error2, | ||
|  | 		         PL_CHARS, expected, | ||
|  | 		         PL_TERM, actual, | ||
|  | 		       PL_VARIABLE) ) | ||
|  |     return PL_raise_exception(ex); | ||
|  | 
 | ||
|  |   return FALSE; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static int | ||
|  | syntax_error(const char *culprit) | ||
|  | { term_t ex; | ||
|  | 
 | ||
|  |   if ( (ex = PL_new_term_ref()) && | ||
|  |        PL_unify_term(ex, | ||
|  | 		     PL_FUNCTOR, FUNCTOR_error2, | ||
|  | 		       PL_FUNCTOR, FUNCTOR_syntax_error1, | ||
|  | 		         PL_CHARS, culprit, | ||
|  | 		       PL_VARIABLE) ) | ||
|  |     return PL_raise_exception(ex); | ||
|  | 
 | ||
|  |   return FALSE; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static int | ||
|  | representation_error(const char *culprit) | ||
|  | { term_t ex; | ||
|  | 
 | ||
|  |   if ( (ex = PL_new_term_ref()) && | ||
|  |        PL_unify_term(ex, | ||
|  | 		     PL_FUNCTOR, FUNCTOR_error2, | ||
|  | 		       PL_FUNCTOR, FUNCTOR_representation_error1, | ||
|  | 		         PL_CHARS, culprit, | ||
|  | 		       PL_VARIABLE) ) | ||
|  |     return PL_raise_exception(ex); | ||
|  | 
 | ||
|  |   return FALSE; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 		 /*******************************
 | ||
|  | 		 *	       PROLOG		* | ||
|  | 		 *******************************/ | ||
|  | 
 | ||
|  | /** turtle_name(+Atom) is semidet.
 | ||
|  | 
 | ||
|  | True if Atom is a valid Turtle identifier | ||
|  | */ | ||
|  | 
 | ||
|  | static inline int | ||
|  | wcis_name_char(int c) | ||
|  | { return wcis_name_start_char(c) || | ||
|  |          wcis_name_extender_char(c); | ||
|  | } | ||
|  | 
 | ||
|  | /** turtle_name_start_char(+Int) is semidet.
 | ||
|  | */ | ||
|  | 
 | ||
|  | static foreign_t | ||
|  | turtle_name_start_char(term_t Code) | ||
|  | { int c; | ||
|  | 
 | ||
|  |   if ( !PL_get_integer(Code, &c) ) | ||
|  |     return type_error(Code, "code"); | ||
|  |   if ( !wcis_name_start_char(c) ) | ||
|  |     return FALSE; | ||
|  | 
 | ||
|  |   return TRUE; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /** turtle_name(+Atom) is semidet.
 | ||
|  | */ | ||
|  | 
 | ||
|  | static foreign_t | ||
|  | turtle_name(term_t name) | ||
|  | { char *s; | ||
|  |   pl_wchar_t *w; | ||
|  |   size_t len; | ||
|  | 
 | ||
|  |   if ( PL_get_nchars(name, &len, &s, CVT_ATOM) ) | ||
|  |   { const char *e = &s[len]; | ||
|  | 
 | ||
|  |     if ( !wcis_name_start_char(s[0]&0xff) ) | ||
|  |       return FALSE; | ||
|  |     for(s++; s<e; s++) | ||
|  |     { if ( !wcis_name_char(s[0]&0xff) ) | ||
|  | 	return FALSE; | ||
|  |     } | ||
|  |     return TRUE; | ||
|  |   } else if ( PL_get_wchars(name, &len, &w, CVT_ATOM|CVT_EXCEPTION) ) | ||
|  |   { const pl_wchar_t *e = &w[len]; | ||
|  | 
 | ||
|  |     if ( !wcis_name_start_char(w[0]) ) | ||
|  |       return FALSE; | ||
|  |     for(w++; w<e; w++) | ||
|  |     { if ( !wcis_name_char(w[0]) ) | ||
|  | 	return FALSE; | ||
|  |     } | ||
|  |     return TRUE; | ||
|  |   } else | ||
|  |     return FALSE; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | typedef struct charbuf | ||
|  | { pl_wchar_t *base; | ||
|  |   pl_wchar_t *here; | ||
|  |   pl_wchar_t *end; | ||
|  |   pl_wchar_t tmp[256]; | ||
|  | } charbuf; | ||
|  | 
 | ||
|  | 
 | ||
|  | static void | ||
|  | init_charbuf(charbuf *cb) | ||
|  | { cb->base = cb->here = cb->tmp; | ||
|  |   cb->end = &cb->tmp[sizeof(cb->tmp)/sizeof(pl_wchar_t)]; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static int | ||
|  | add_charbuf(charbuf *cb, int c) | ||
|  | { if ( cb->here < cb->end ) | ||
|  |   { *cb->here++ = c; | ||
|  |   } else | ||
|  |   { size_t len = (cb->end-cb->base); | ||
|  | 
 | ||
|  |     if ( cb->base == cb->tmp ) | ||
|  |     { pl_wchar_t *n = PL_malloc(len*2*sizeof(pl_wchar_t)); | ||
|  |       memcpy(n, cb->base, sizeof(cb->tmp)); | ||
|  |       cb->base = n; | ||
|  |     } else | ||
|  |     { cb->base = PL_realloc(cb->base, len*2*sizeof(pl_wchar_t)); | ||
|  |     } | ||
|  |     cb->here = &cb->base[len]; | ||
|  |     cb->end = &cb->base[len*2]; | ||
|  |     *cb->here++ = c; | ||
|  |   } | ||
|  | 
 | ||
|  |   return TRUE; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static void | ||
|  | free_charbuf(charbuf *cb) | ||
|  | { if ( cb->base != cb->tmp ) | ||
|  |     PL_free(cb->base); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /** turtle_read_name(+C0, +Stream, -C, -Name) is semidet.
 | ||
|  | */ | ||
|  | 
 | ||
|  | static foreign_t | ||
|  | turtle_read_name(term_t C0, term_t Stream, term_t C, term_t Name) | ||
|  | { int c; | ||
|  |   charbuf b; | ||
|  |   IOSTREAM *in; | ||
|  | 
 | ||
|  |   if ( !PL_get_integer(C0, &c) ) | ||
|  |     return type_error(C0, "code"); | ||
|  |   if ( !wcis_name_start_char(c) ) | ||
|  |     return FALSE; | ||
|  | 
 | ||
|  |   if ( !PL_get_stream_handle(Stream, &in) ) | ||
|  |     return FALSE; | ||
|  | 
 | ||
|  |   init_charbuf(&b); | ||
|  |   add_charbuf(&b, c); | ||
|  | 
 | ||
|  |   for(;;) | ||
|  |   { int c = Sgetcode(in); | ||
|  | 
 | ||
|  |     if ( wcis_name_char(c) ) | ||
|  |     { add_charbuf(&b, c); | ||
|  |     } else | ||
|  |     { int rc = ( PL_unify_integer(C, c) && | ||
|  | 		 PL_unify_wchars(Name, PL_ATOM, b.here-b.base, b.base) ); | ||
|  | 
 | ||
|  |       free_charbuf(&b); | ||
|  |       PL_release_stream(in); | ||
|  | 
 | ||
|  |       return rc; | ||
|  |     } | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static int | ||
|  | read_hN(IOSTREAM *in, int digits, int *value) | ||
|  | { int d = digits; | ||
|  |   int v = 0; | ||
|  | 
 | ||
|  |   while ( d-- > 0 ) | ||
|  |   { int c = Sgetcode(in); | ||
|  | 
 | ||
|  |     if ( c >= '0' && c <= '9' ) | ||
|  |       v = (v<<4) + c - '0'; | ||
|  |     else if ( c >= 'A' && c <= 'F' ) | ||
|  |       v = (v<<4) + c + 10 - 'A'; | ||
|  |     else if ( c >= 'a' && c <= 'f' ) | ||
|  |       v = (v<<4) + c + 10 - 'a'; | ||
|  |     else | ||
|  |     { if ( digits == 4 ) | ||
|  | 	return syntax_error("Illegal \\uNNNN in string"); | ||
|  |       else | ||
|  | 	return syntax_error("Illegal \\UNNNNNNNN in string"); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   *value = v; | ||
|  |   return TRUE; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static int | ||
|  | string_escape(IOSTREAM *in, int c, int *value) | ||
|  | { int esc; | ||
|  | 
 | ||
|  |   switch(c) | ||
|  |   { case 'n': esc = '\n'; break; | ||
|  |     case '"': esc = '"';  break; | ||
|  |     case '\\':esc = '\\'; break; | ||
|  |     case 't': esc = '\t'; break; | ||
|  |     case 'r': esc = '\r'; break; | ||
|  |     case 'u': | ||
|  |       if ( !read_hN(in, 4, &esc) ) | ||
|  | 	return FALSE; | ||
|  |       break; | ||
|  |     case 'U': | ||
|  |       if ( !read_hN(in, 8, &esc) ) | ||
|  | 	return FALSE; | ||
|  |       break; | ||
|  |     default: | ||
|  |       return syntax_error("illegal escape in string"); | ||
|  |   } | ||
|  | 
 | ||
|  |   *value = esc; | ||
|  |   return TRUE; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /** turtle_read_string(+C0, +Stream, -C, -Value:atom) is semidet.
 | ||
|  | */ | ||
|  | 
 | ||
|  | static foreign_t | ||
|  | turtle_read_string(term_t C0, term_t Stream, term_t C, term_t Value) | ||
|  | { int c; | ||
|  |   charbuf b; | ||
|  |   IOSTREAM *in; | ||
|  |   int endlen = 1; | ||
|  | 
 | ||
|  |   if ( !PL_get_integer(C0, &c) ) | ||
|  |     return type_error(C0, "code"); | ||
|  |   if ( c != '"' ) | ||
|  |     return FALSE; | ||
|  | 
 | ||
|  |   if ( !PL_get_stream_handle(Stream, &in) ) | ||
|  |     return FALSE; | ||
|  | 
 | ||
|  |   init_charbuf(&b); | ||
|  | 
 | ||
|  |   c = Sgetcode(in); | ||
|  |   if ( c == '"' ) | ||
|  |   { c = Sgetcode(in); | ||
|  |     if ( c == '"' )			/* """...""" */ | ||
|  |     { endlen = 3; | ||
|  |       c = Sgetcode(in); | ||
|  |     } else | ||
|  |     { PL_release_stream(in); | ||
|  |       return (PL_unify_integer(C, c) && | ||
|  | 	      PL_unify_atom(Value, ATOM_)); | ||
|  |     } | ||
|  |   } | ||
|  | 
 | ||
|  |   for(;;c = Sgetcode(in)) | ||
|  |   { if ( c == -1 ) | ||
|  |     { free_charbuf(&b); | ||
|  |       PL_release_stream(in); | ||
|  |       return syntax_error("eof_in_string"); | ||
|  |     } else if ( c == '"' ) | ||
|  |     { int count = 1; | ||
|  | 
 | ||
|  |       for(count=1; count<endlen; ) | ||
|  |       { if ( (c=Sgetcode(in)) == '"' ) | ||
|  | 	  count++; | ||
|  | 	else | ||
|  | 	  break; | ||
|  |       } | ||
|  | 
 | ||
|  |       if ( count == endlen ) | ||
|  |       { int rc; | ||
|  | 
 | ||
|  | 	c = Sgetcode(in); | ||
|  | 	rc = (PL_unify_integer(C, c) && | ||
|  | 	      PL_unify_wchars(Value, PL_ATOM, b.here-b.base, b.base)); | ||
|  | 	free_charbuf(&b); | ||
|  | 	PL_release_stream(in); | ||
|  | 	return rc; | ||
|  |       } | ||
|  | 
 | ||
|  |       while(count-- > 0) | ||
|  | 	add_charbuf(&b, '"'); | ||
|  |       add_charbuf(&b, c); | ||
|  |     } else if ( c == '\\' ) | ||
|  |     { int esc; | ||
|  | 
 | ||
|  |       c = Sgetcode(in); | ||
|  |       if ( !string_escape(in, c, &esc) ) | ||
|  |       { free_charbuf(&b); | ||
|  | 	PL_release_stream(in); | ||
|  | 	return FALSE; | ||
|  |       } | ||
|  |       add_charbuf(&b, esc); | ||
|  |     } else | ||
|  |     { add_charbuf(&b, c); | ||
|  |     } | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /** turtle_read_relative_uri(+C0, +Stream, -C, -Value:atom) is semidet.
 | ||
|  | */ | ||
|  | 
 | ||
|  | static foreign_t | ||
|  | turtle_read_relative_uri(term_t C0, term_t Stream, term_t C, term_t Value) | ||
|  | { int c; | ||
|  |   charbuf b; | ||
|  |   IOSTREAM *in; | ||
|  | 
 | ||
|  |   if ( !PL_get_integer(C0, &c) ) | ||
|  |     return type_error(C0, "code"); | ||
|  |   if ( c != '<' ) | ||
|  |     return FALSE; | ||
|  | 
 | ||
|  |   if ( !PL_get_stream_handle(Stream, &in) ) | ||
|  |     return FALSE; | ||
|  | 
 | ||
|  |   init_charbuf(&b); | ||
|  |   c = Sgetcode(in); | ||
|  |   for(; ; c = Sgetcode(in)) | ||
|  |   { if ( c == '>' ) | ||
|  |     { int rc; | ||
|  | 
 | ||
|  |       c = Sgetcode(in); | ||
|  |       rc = (PL_unify_integer(C, c) && | ||
|  | 	    PL_unify_wchars(Value, PL_ATOM, b.here-b.base, b.base)); | ||
|  |       PL_release_stream(in); | ||
|  |       free_charbuf(&b); | ||
|  |       return rc; | ||
|  |     } else if ( c == '\\' ) | ||
|  |     { int esc; | ||
|  | 
 | ||
|  |       c = Sgetcode(in); | ||
|  |       if ( c == '>' ) | ||
|  |       { add_charbuf(&b, c); | ||
|  |       } else if ( string_escape(in, c, &esc) ) | ||
|  |       { add_charbuf(&b, esc); | ||
|  |       } else | ||
|  |       { free_charbuf(&b); | ||
|  | 	PL_release_stream(in); | ||
|  | 	return FALSE; | ||
|  |       } | ||
|  |     } else if ( c == -1 ) | ||
|  |     { free_charbuf(&b); | ||
|  |       PL_release_stream(in); | ||
|  |       return syntax_error("eof_in_uri"); | ||
|  |     } else | ||
|  |     { add_charbuf(&b, c); | ||
|  |     } | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | 		 /*******************************
 | ||
|  | 		 *	     WRITING		* | ||
|  | 		 *******************************/ | ||
|  | 
 | ||
|  | static int | ||
|  | ttl_put_uesc(IOSTREAM *s, int c) | ||
|  | { if ( c <= 0xffff ) | ||
|  |     return Sfprintf(s, "\\u%04x", (unsigned)c); | ||
|  |   else | ||
|  |     return Sfprintf(s, "\\U%08x", (unsigned)c); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static int | ||
|  | ttl_put_character(IOSTREAM *s, int c) | ||
|  | { if ( c >= 32 && c <= 126 ) | ||
|  |     return Sputcode(c, s); | ||
|  |   if ( c <= 31 ) | ||
|  |     return ttl_put_uesc(s, c); | ||
|  |   if ( c >= 127 && c < 0x10ffff ) | ||
|  |   { if ( s->encoding == ENC_ASCII ) | ||
|  |       return ttl_put_uesc(s, c); | ||
|  |     if ( s->encoding == ENC_ISO_LATIN_1 && c > 255 ) | ||
|  |       return ttl_put_uesc(s, c); | ||
|  |     return Sputcode(c, s); | ||
|  |   } | ||
|  | 
 | ||
|  |   representation_error("turtle_character"); | ||
|  |   return -1; | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static int | ||
|  | ttl_put_echaracter(IOSTREAM *s, int c) | ||
|  | { int c2; | ||
|  | 
 | ||
|  |   switch(c) | ||
|  |   { case '\t': c2 = 't'; break; | ||
|  |     case '\n': c2 = 'n'; break; | ||
|  |     case '\r': c2 = 'r'; break; | ||
|  |     default: | ||
|  |       return ttl_put_character(s, c); | ||
|  |   } | ||
|  | 
 | ||
|  |   Sputcode('\\', s); | ||
|  | 
 | ||
|  |   return Sputcode(c2, s); | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static int | ||
|  | ttl_put_scharacter(IOSTREAM *s, int c) | ||
|  | { switch(c) | ||
|  |   { case '"': | ||
|  |       Sputcode('\\', s); | ||
|  |       return Sputcode('"', s); | ||
|  |     case '\\': | ||
|  |       Sputcode('\\', s); | ||
|  |       return Sputcode('\\', s); | ||
|  |     default: | ||
|  |       return ttl_put_echaracter(s, c); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static foreign_t | ||
|  | turtle_write_quoted_string(term_t Stream, term_t Value) | ||
|  | { size_t len; | ||
|  |   char *s; | ||
|  |   pl_wchar_t *w; | ||
|  |   IOSTREAM *out; | ||
|  | 
 | ||
|  |   if ( !PL_get_stream_handle(Stream, &out) ) | ||
|  |     return FALSE; | ||
|  | 
 | ||
|  |   if ( PL_get_nchars(Value, &len, &s, CVT_ATOM|CVT_STRING) ) | ||
|  |   { const char *e = &s[len]; | ||
|  | 
 | ||
|  |     Sputcode('"', out); | ||
|  |     for(; s<e; s++) | ||
|  |     { if ( ttl_put_scharacter(out, s[0]&0xff) < 0 ) | ||
|  | 	break; | ||
|  |     } | ||
|  |     Sputcode('"', out); | ||
|  |     return PL_release_stream(out); | ||
|  |   } else if ( PL_get_wchars(Value, &len, &w, CVT_ATOM|CVT_EXCEPTION) ) | ||
|  |   { const pl_wchar_t *e = &w[len]; | ||
|  | 
 | ||
|  |     Sputcode('"', out); | ||
|  |     for(; w<e; w++) | ||
|  |     { if ( ttl_put_scharacter(out, w[0]) < 0 ) | ||
|  | 	break; | ||
|  |     } | ||
|  |     Sputcode('"', out); | ||
|  |     return PL_release_stream(out); | ||
|  |   } else | ||
|  |   { PL_release_stream(out); | ||
|  |     return FALSE; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | static int | ||
|  | ttl_put_ucharacter(IOSTREAM *s, int c) | ||
|  | { switch(c) | ||
|  |   { case '>': | ||
|  |       Sputcode('\\', s); | ||
|  |       return Sputcode('>', s); | ||
|  |     default: | ||
|  |       return ttl_put_character(s, c); | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | /** turtle_write_uri(+Stream, +URI) is det.
 | ||
|  | */ | ||
|  | 
 | ||
|  | static foreign_t | ||
|  | turtle_write_uri(term_t Stream, term_t Value) | ||
|  | { size_t len; | ||
|  |   char *s; | ||
|  |   pl_wchar_t *w; | ||
|  |   IOSTREAM *out; | ||
|  | 
 | ||
|  |   if ( !PL_get_stream_handle(Stream, &out) ) | ||
|  |     return FALSE; | ||
|  | 
 | ||
|  |   if ( PL_get_nchars(Value, &len, &s, CVT_ATOM|CVT_STRING) ) | ||
|  |   { const char *e = &s[len]; | ||
|  | 
 | ||
|  |     Sputcode('<', out); | ||
|  |     for(; s<e; s++) | ||
|  |     { if ( ttl_put_ucharacter(out, s[0]&0xff) < 0 ) | ||
|  | 	break; | ||
|  |     } | ||
|  |     Sputcode('>', out); | ||
|  |     return PL_release_stream(out); | ||
|  |   } else if ( PL_get_wchars(Value, &len, &w, CVT_ATOM|CVT_EXCEPTION) ) | ||
|  |   { const pl_wchar_t *e = &w[len]; | ||
|  | 
 | ||
|  |     Sputcode('<', out); | ||
|  |     for(; w<e; w++) | ||
|  |     { if ( ttl_put_ucharacter(out, w[0]) < 0 ) | ||
|  | 	break; | ||
|  |     } | ||
|  |     Sputcode('>', out); | ||
|  |     return PL_release_stream(out); | ||
|  |   } else | ||
|  |   { PL_release_stream(out); | ||
|  |     return FALSE; | ||
|  |   } | ||
|  | } | ||
|  | 
 | ||
|  | 
 | ||
|  | 
 | ||
|  | 		 /*******************************
 | ||
|  | 		 *	    REGISTRATION	* | ||
|  | 		 *******************************/ | ||
|  | 
 | ||
|  | #define MKFUNCTOR(n,a) \
 | ||
|  | 	FUNCTOR_ ## n ## a = PL_new_functor(PL_new_atom(#n), a) | ||
|  | #define MKATOM(n) \
 | ||
|  | 	ATOM_ ## n = PL_new_atom(#n) | ||
|  | 
 | ||
|  | install_t | ||
|  | install_turtle() | ||
|  | { MKFUNCTOR(error, 2); | ||
|  |   MKFUNCTOR(type_error, 2); | ||
|  |   MKFUNCTOR(syntax_error, 1); | ||
|  |   MKFUNCTOR(representation_error, 1); | ||
|  |   ATOM_ = PL_new_atom(""); | ||
|  | 
 | ||
|  |   PL_register_foreign("turtle_name_start_char", | ||
|  | 		      			    1, turtle_name_start_char, 0); | ||
|  |   PL_register_foreign("turtle_name",        1, turtle_name,        0); | ||
|  |   PL_register_foreign("turtle_read_name",   4, turtle_read_name,   0); | ||
|  |   PL_register_foreign("turtle_read_string", 4, turtle_read_string, 0); | ||
|  |   PL_register_foreign("turtle_read_relative_uri", | ||
|  | 					    4, turtle_read_relative_uri, 0); | ||
|  |   PL_register_foreign("turtle_write_quoted_string", | ||
|  | 					    2, turtle_write_quoted_string, 0); | ||
|  |   PL_register_foreign("turtle_write_uri",   2, turtle_write_uri,   0); | ||
|  | } |