assembly fixes
more support for readline, including getting more stuff from read.
This commit is contained in:
		
							
								
								
									
										10
									
								
								C/absmi.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								C/absmi.c
									
									
									
									
									
								
							| @@ -1667,7 +1667,7 @@ Yap_absmi(int inp) | |||||||
| #ifdef DEPTH_LIMIT | #ifdef DEPTH_LIMIT | ||||||
| 	  YENV[E_DEPTH] = DEPTH; | 	  YENV[E_DEPTH] = DEPTH; | ||||||
| #endif	/* DEPTH_LIMIT */ | #endif	/* DEPTH_LIMIT */ | ||||||
| 	  SET_ASP(YREG, E_CB*sizeof(CELL)); | 	  SET_ASP(YREG, PREG->u.Osbpi.s); | ||||||
| 	  saveregs(); | 	  saveregs(); | ||||||
| 	  if (!Yap_gcl(sz, arity, YENV, PREG)) { | 	  if (!Yap_gcl(sz, arity, YENV, PREG)) { | ||||||
| 	    Yap_Error(OUT_OF_STACK_ERROR,TermNil,Yap_ErrorMessage); | 	    Yap_Error(OUT_OF_STACK_ERROR,TermNil,Yap_ErrorMessage); | ||||||
| @@ -7469,7 +7469,7 @@ Yap_absmi(int inp) | |||||||
| 	else ASP = (CELL *)(((char *)YREG) +  PREG->u.Osbpp.s); | 	else ASP = (CELL *)(((char *)YREG) +  PREG->u.Osbpp.s); | ||||||
|       } |       } | ||||||
| #else | #else | ||||||
|       SET_ASP(YREG, 0); |       SET_ASP(YREG, PREG->u.Osbpp.s); | ||||||
|       /* for slots to work */ |       /* for slots to work */ | ||||||
| #endif /* FROZEN_STACKS */ | #endif /* FROZEN_STACKS */ | ||||||
| #ifdef LOW_LEVEL_TRACER | #ifdef LOW_LEVEL_TRACER | ||||||
| @@ -7513,7 +7513,7 @@ Yap_absmi(int inp) | |||||||
| 	  else ASP = YREG+E_CB; | 	  else ASP = YREG+E_CB; | ||||||
| 	} | 	} | ||||||
| #else | #else | ||||||
| 	SET_ASP(YREG, 0); | 	SET_ASP(YREG, E_CB*sizeof(CELL)); | ||||||
| 	/* for slots to work */ | 	/* for slots to work */ | ||||||
| #endif /* FROZEN_STACKS */ | #endif /* FROZEN_STACKS */ | ||||||
| 	pt0 = PREG->u.pp.p; | 	pt0 = PREG->u.pp.p; | ||||||
| @@ -7600,7 +7600,7 @@ Yap_absmi(int inp) | |||||||
| 	else ASP = (CELL *)(((char *)YREG) +  PREG->u.Osbpp.s); | 	else ASP = (CELL *)(((char *)YREG) +  PREG->u.Osbpp.s); | ||||||
|       } |       } | ||||||
| #else | #else | ||||||
|       SET_ASP(YREG, 0); |       SET_ASP(YREG, PREG->u.Osbpp.s); | ||||||
|       /* for slots to work */ |       /* for slots to work */ | ||||||
| #endif /* FROZEN_STACKS */ | #endif /* FROZEN_STACKS */ | ||||||
|       { |       { | ||||||
| @@ -7833,7 +7833,7 @@ Yap_absmi(int inp) | |||||||
|       ENDCACHE_Y(); |       ENDCACHE_Y(); | ||||||
|  |  | ||||||
|       Yap_PrologMode = UserCCallMode; |       Yap_PrologMode = UserCCallMode; | ||||||
|       SET_ASP(YREG, 0); |       SET_ASP(YREG, E_CB*sizeof(CELL)); | ||||||
|       /* for slots to work */ |       /* for slots to work */ | ||||||
|       Yap_StartSlots(); |       Yap_StartSlots(); | ||||||
|       saveregs(); |       saveregs(); | ||||||
|   | |||||||
| @@ -172,6 +172,10 @@ low_level_trace(yap_low_level_port port, PredEntry *pred, CELL *args) | |||||||
|   LOCK(Yap_heap_regs->low_level_trace_lock); |   LOCK(Yap_heap_regs->low_level_trace_lock); | ||||||
|   sc = Yap_heap_regs; |   sc = Yap_heap_regs; | ||||||
|   vsc_count++; |   vsc_count++; | ||||||
|  |   if (vsc_count == 471321) | ||||||
|  |     jmp_deb(1); | ||||||
|  |   if (vsc_count < 471300) | ||||||
|  |     return; | ||||||
| #ifdef THREADS | #ifdef THREADS | ||||||
|   MY_ThreadHandle.thread_inst_count++; |   MY_ThreadHandle.thread_inst_count++; | ||||||
| #endif   | #endif   | ||||||
|   | |||||||
| @@ -148,12 +148,10 @@ | |||||||
| 	  if (erase) { | 	  if (erase) { | ||||||
| 	    /* at this point, we are the only ones accessing the clause, | 	    /* at this point, we are the only ones accessing the clause, | ||||||
| 	       hence we don't need to have a lock it */ | 	       hence we don't need to have a lock it */ | ||||||
| 	    saveregs(); |  | ||||||
| 	    if (cl->ClFlags & ErasedMask)  | 	    if (cl->ClFlags & ErasedMask)  | ||||||
| 	      Yap_ErLogUpdIndex(cl); | 	      Yap_ErLogUpdIndex(cl); | ||||||
| 	    else | 	    else | ||||||
| 	      Yap_CleanUpIndex(cl); | 	      Yap_CleanUpIndex(cl); | ||||||
| 	    setregs(); |  | ||||||
| 	  } | 	  } | ||||||
| 	  UNLOCK(ap->PELock); | 	  UNLOCK(ap->PELock); | ||||||
| 	} else { | 	} else { | ||||||
|   | |||||||
| @@ -229,6 +229,10 @@ | |||||||
| #undef  HAVE_REGEXEC | #undef  HAVE_REGEXEC | ||||||
| #undef  HAVE_RENAME | #undef  HAVE_RENAME | ||||||
| #undef  HAVE_RINT | #undef  HAVE_RINT | ||||||
|  | #undef  HAVE_RL_CLEAR_PENDING_INPUT | ||||||
|  | #undef  HAVE_RL_COMPLETION_MATCHES | ||||||
|  | #undef  HAVE_RL_FILENAME_COMPLETION_FUNCTION | ||||||
|  | #undef  HAVE_RL_INSERT_CLOSE | ||||||
| #undef  HAVE_RL_SET_PROMPT | #undef  HAVE_RL_SET_PROMPT | ||||||
| #undef  HAVE_SBRK | #undef  HAVE_SBRK | ||||||
| #undef  HAVE_SELECT | #undef  HAVE_SELECT | ||||||
| @@ -281,8 +285,6 @@ | |||||||
| #define  TYPE_SELECT_ | #define  TYPE_SELECT_ | ||||||
| #define  MYTYPE(X) MYTYPE1#X | #define  MYTYPE(X) MYTYPE1#X | ||||||
|  |  | ||||||
| #undef  HAVE_DECL_RL_CATCH_SIGNALS |  | ||||||
|  |  | ||||||
| /* define how to pass the address of a function */ | /* define how to pass the address of a function */ | ||||||
| #define FunAdr(Fn)  Fn | #define FunAdr(Fn)  Fn | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1380,7 +1380,11 @@ if test "$yap_cv_readline" != "no" | |||||||
| then | then | ||||||
|   AC_CHECK_HEADERS( readline/readline.h) |   AC_CHECK_HEADERS( readline/readline.h) | ||||||
|   AC_CHECK_HEADERS( readline/history.h) |   AC_CHECK_HEADERS( readline/history.h) | ||||||
|   AC_CHECK_DECL( rl_catch_signals ) |   AC_CHECK_FUNC( rl_completion_matches ) | ||||||
|  |   AC_CHECK_FUNC( rl_insert_close ) | ||||||
|  |   AC_CHECK_FUNC( rl_filename_completion_function ) | ||||||
|  |   AC_CHECK_FUNC( rl_set_prompt ) | ||||||
|  |   AC_CHECK_FUNC( rl_clear_pending_input ) | ||||||
| fi | fi | ||||||
| AC_CHECK_HEADERS(mpi.h) | AC_CHECK_HEADERS(mpi.h) | ||||||
| AC_CHECK_HEADERS(mpe.h) | AC_CHECK_HEADERS(mpe.h) | ||||||
|   | |||||||
| @@ -26,36 +26,6 @@ | |||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| #include "pl-ctype.h" | #include "pl-ctype.h" | ||||||
|  |  | ||||||
| #if __YAP_PROLOG__ |  | ||||||
|  |  | ||||||
| /* support for blank space handling, stolen from pl-read.c */ |  | ||||||
|  |  | ||||||
| #include <pl-umap.c> |  | ||||||
|  |  | ||||||
| 		 /******************************* |  | ||||||
| 		 *     UNICODE CLASSIFIERS	* |  | ||||||
| 		 *******************************/ |  | ||||||
|  |  | ||||||
| #define CharTypeW(c, t, w) \ |  | ||||||
| 	((unsigned)(c) <= 0xff ? (_PL_char_types[(unsigned)(c)] t) \ |  | ||||||
| 			       : (uflagsW(c) & w)) |  | ||||||
|  |  | ||||||
| #define PlBlankW(c)	CharTypeW(c, <= SP, U_SEPARATOR) |  | ||||||
| #define PlUpperW(c)	CharTypeW(c, == UC, U_UPPERCASE) |  | ||||||
| #define PlIdStartW(c)	(c <= 0xff ? (isLower(c)||isUpper(c)||c=='_') \ |  | ||||||
| 				   : uflagsW(c) & U_ID_START) |  | ||||||
| #define PlIdContW(c)	CharTypeW(c, >= UC, U_ID_CONTINUE) |  | ||||||
| #define PlSymbolW(c)	CharTypeW(c, == SY, 0) |  | ||||||
| #define PlPunctW(c)	CharTypeW(c, == PU, 0) |  | ||||||
| #define PlSoloW(c)	CharTypeW(c, == SO, 0) |  | ||||||
|  |  | ||||||
| static int  |  | ||||||
| unicode_separator(pl_wchar_t c) |  | ||||||
| { return PlBlankW(c); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||||||
| This module defines: | This module defines: | ||||||
|  |  | ||||||
|   | |||||||
| @@ -191,6 +191,10 @@ typedef struct | |||||||
|   word culprit;				/* for CVT_nocode/CVT_nochar */ |   word culprit;				/* for CVT_nocode/CVT_nochar */ | ||||||
| } CVT_result; | } CVT_result; | ||||||
|  |  | ||||||
|  | #define MAXNEWLINES	    5		/* maximum # of newlines in atom */ | ||||||
|  |  | ||||||
|  | #define LONGATOM_CHECK	    0x01	/* read/1: error on intptr_t atoms */ | ||||||
|  |  | ||||||
| /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||||||
| Operator types.  NOTE: if you change OP_*, check operatorTypeToAtom()! | Operator types.  NOTE: if you change OP_*, check operatorTypeToAtom()! | ||||||
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | ||||||
| @@ -686,7 +690,8 @@ extern PL_local_data_t lds; | |||||||
|  |  | ||||||
| #define source_line_no		(LD->read_source.line) | #define source_line_no		(LD->read_source.line) | ||||||
| #define source_file_name	(LD->read_source.file) | #define source_file_name	(LD->read_source.file) | ||||||
|  | #define source_line_pos		(LD->read_source.linepos) | ||||||
|  | #define source_char_no		(LD->read_source.character) | ||||||
|  |  | ||||||
| /* Support PL_LOCK in the interface */ | /* Support PL_LOCK in the interface */ | ||||||
| #if THREADS | #if THREADS | ||||||
| @@ -982,7 +987,9 @@ word pl_noprotocol(void); | |||||||
| IOSTREAM *PL_current_input(void); | IOSTREAM *PL_current_input(void); | ||||||
| IOSTREAM *PL_current_output(void); | IOSTREAM *PL_current_output(void); | ||||||
|  |  | ||||||
| int reportStreamError(IOSTREAM *s); | extern int reportStreamError(IOSTREAM *s); | ||||||
|  |  | ||||||
|  | extern int digitValue(int b, int c); | ||||||
|  |  | ||||||
| PL_EXPORT(int)  	PL_unify_stream(term_t t, IOSTREAM *s); | PL_EXPORT(int)  	PL_unify_stream(term_t t, IOSTREAM *s); | ||||||
| PL_EXPORT(int)  	PL_unify_stream_or_alias(term_t t, IOSTREAM *s); | PL_EXPORT(int)  	PL_unify_stream_or_alias(term_t t, IOSTREAM *s); | ||||||
| @@ -990,6 +997,7 @@ PL_EXPORT(int)  	PL_get_stream_handle(term_t t, IOSTREAM **s); | |||||||
| PL_EXPORT(void)  	PL_write_prompt(int); | PL_EXPORT(void)  	PL_write_prompt(int); | ||||||
| PL_EXPORT(int) 		PL_release_stream(IOSTREAM *s); | PL_EXPORT(int) 		PL_release_stream(IOSTREAM *s); | ||||||
|  |  | ||||||
|  |  | ||||||
| COMMON(atom_t) 		fileNameStream(IOSTREAM *s); | COMMON(atom_t) 		fileNameStream(IOSTREAM *s); | ||||||
| COMMON(int) 		streamStatus(IOSTREAM *s); | COMMON(int) 		streamStatus(IOSTREAM *s); | ||||||
|  |  | ||||||
| @@ -1005,6 +1013,11 @@ COMMON(atom_t)		encoding_to_atom(IOENC enc); | |||||||
| COMMON(int) 		pl_see(term_t f); | COMMON(int) 		pl_see(term_t f); | ||||||
| COMMON(int) 		pl_seen(void); | COMMON(int) 		pl_seen(void); | ||||||
|  |  | ||||||
|  | COMMON(int)		unicode_separator(pl_wchar_t c); | ||||||
|  | COMMON(word) 		pl_raw_read(term_t term); | ||||||
|  | COMMON(word) 		pl_raw_read2(term_t stream, term_t term); | ||||||
|  |  | ||||||
|  |  | ||||||
| /**** stuff from pl-error.c ****/ | /**** stuff from pl-error.c ****/ | ||||||
| extern void		outOfCore(void); | extern void		outOfCore(void); | ||||||
| extern void		fatalError(const char *fm, ...); | extern void		fatalError(const char *fm, ...); | ||||||
| @@ -1102,8 +1115,6 @@ COMMON(int) 		numberVars(term_t t, nv_options *opts, int n ARG_LD); | |||||||
| COMMON(Buffer)		codes_or_chars_to_buffer(term_t l, unsigned int flags, | COMMON(Buffer)		codes_or_chars_to_buffer(term_t l, unsigned int flags, | ||||||
| 						 int wide, CVT_result *status); | 						 int wide, CVT_result *status); | ||||||
|  |  | ||||||
| COMMON(int)		uflagsW(int code); |  | ||||||
|  |  | ||||||
| static inline word | static inline word | ||||||
| setBoolean(int *flag, term_t old, term_t new) | setBoolean(int *flag, term_t old, term_t new) | ||||||
| { if ( !PL_unify_bool_ex(old, *flag) || | { if ( !PL_unify_bool_ex(old, *flag) || | ||||||
|   | |||||||
| @@ -1,18 +1,74 @@ | |||||||
|  |  | ||||||
| #include "pl-incl.h" | #include "pl-incl.h" | ||||||
|  | #include "pl-ctype.h" | ||||||
|  | #include "pl-utf8.h" | ||||||
|  | #include "pl-dtoa.h" | ||||||
|  | #include "pl-umap.c"			/* Unicode map */ | ||||||
|  |  | ||||||
|  | typedef       unsigned char * ucharp; | ||||||
|  | typedef const unsigned char * cucharp; | ||||||
|  |  | ||||||
|  | #define utf8_get_uchar(s, chr) (ucharp)utf8_get_char((char *)(s), chr) | ||||||
|  |  | ||||||
|  | #define FASTBUFFERSIZE	256	/* read quickly upto this size */ | ||||||
|  |  | ||||||
|  | struct read_buffer | ||||||
|  | { int	size;			/* current size of read buffer */ | ||||||
|  |   unsigned char *base;		/* base of read buffer */ | ||||||
|  |   unsigned char *here;		/* current position in read buffer */ | ||||||
|  |   unsigned char *end;		/* end of the valid buffer */ | ||||||
|  |  | ||||||
|  |   IOSTREAM *stream;		/* stream we are reading from */ | ||||||
|  |   unsigned char fast[FASTBUFFERSIZE];	/* Quick internal buffer */ | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| typedef struct | typedef struct | ||||||
| { | { unsigned char *here;			/* current character */ | ||||||
|   term_t	varnames;		/* Report variables+names */   |   unsigned char *base;			/* base of clause */ | ||||||
|  |   unsigned char *end;			/* end of the clause */ | ||||||
|  |   unsigned char *token_start;		/* start of most recent read token */ | ||||||
|   IOSTREAM *stream; |   IOSTREAM *stream; | ||||||
|   int		has_exception;		/* exception is raised */ |   int		has_exception;		/* exception is raised */ | ||||||
|  |  | ||||||
|  |   unsigned char *posp;			/* position pointer */ | ||||||
|  |   size_t	posi;			/* position number */ | ||||||
|  |  | ||||||
|  |   unsigned int	flags;			/* Module syntax flags */ | ||||||
|  |   int		styleCheck;		/* style-checking mask */ | ||||||
|  |   bool		backquoted_string;	/* Read `hello` as string */ | ||||||
|  |   int	       *char_conversion_table;	/* active conversion table */ | ||||||
|  |  | ||||||
|   term_t	exception;		/* raised exception */ |   term_t	exception;		/* raised exception */ | ||||||
|  |   term_t	varnames;		/* Report variables+names */   | ||||||
|  |   int		strictness;		/* Strictness level */ | ||||||
|  |  | ||||||
|  |   term_t	comments;		/* Report comments */ | ||||||
|  |  | ||||||
|  |   struct read_buffer _rb;		/* keep read characters here */ | ||||||
| } read_data, *ReadData; | } read_data, *ReadData; | ||||||
|  |  | ||||||
|  | #define	rdhere		  (_PL_rd->here) | ||||||
|  | #define	rdbase		  (_PL_rd->base) | ||||||
|  | #define	rdend		  (_PL_rd->end) | ||||||
|  | #define	last_token_start  (_PL_rd->token_start) | ||||||
|  | #define	rb		  (_PL_rd->_rb) | ||||||
|  |  | ||||||
|  | #define DO_CHARESCAPE true(_PL_rd, CHARESCAPE) | ||||||
|  |  | ||||||
|  | extern IOFUNCTIONS Sstringfunctions; | ||||||
|  |  | ||||||
|  | static bool | ||||||
|  | isStringStream(IOSTREAM *s) | ||||||
|  | { return s->functions == &Sstringfunctions; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static void | static void | ||||||
| init_read_data(ReadData _PL_rd, IOSTREAM *in ARG_LD) | init_read_data(ReadData _PL_rd, IOSTREAM *in ARG_LD) | ||||||
| {  | {  memset(_PL_rd, 0, sizeof(*_PL_rd));	/* optimise! */ | ||||||
|  |  | ||||||
|   _PL_rd->varnames = 0; |   _PL_rd->varnames = 0; | ||||||
|   _PL_rd->stream = in; |   _PL_rd->stream = in; | ||||||
|   _PL_rd->has_exception = 0; |   _PL_rd->has_exception = 0; | ||||||
| @@ -31,6 +87,878 @@ read_term(term_t t, ReadData rd ARG_LD) | |||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static void	  addUTF8Buffer(Buffer b, int c); | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | addUTF8Buffer(Buffer b, int c) | ||||||
|  | { if ( c >= 0x80 ) | ||||||
|  |   { char buf[6]; | ||||||
|  |     char *p, *end; | ||||||
|  |  | ||||||
|  |     end = utf8_put_char(buf, c); | ||||||
|  |     for(p=buf; p<end; p++) | ||||||
|  |     { addBuffer(b, *p&0xff, char); | ||||||
|  |     } | ||||||
|  |   } else | ||||||
|  |   { addBuffer(b, c, char); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 		 /******************************* | ||||||
|  | 		 *     UNICODE CLASSIFIERS	* | ||||||
|  | 		 *******************************/ | ||||||
|  |  | ||||||
|  | #define CharTypeW(c, t, w) \ | ||||||
|  | 	((unsigned)(c) <= 0xff ? (_PL_char_types[(unsigned)(c)] t) \ | ||||||
|  | 			       : (uflagsW(c) & w)) | ||||||
|  |  | ||||||
|  | #define PlBlankW(c)	CharTypeW(c, <= SP, U_SEPARATOR) | ||||||
|  | #define PlUpperW(c)	CharTypeW(c, == UC, U_UPPERCASE) | ||||||
|  | #define PlIdStartW(c)	(c <= 0xff ? (isLower(c)||isUpper(c)||c=='_') \ | ||||||
|  | 				   : uflagsW(c) & U_ID_START) | ||||||
|  | #define PlIdContW(c)	CharTypeW(c, >= UC, U_ID_CONTINUE) | ||||||
|  | #define PlSymbolW(c)	CharTypeW(c, == SY, 0) | ||||||
|  | #define PlPunctW(c)	CharTypeW(c, == PU, 0) | ||||||
|  | #define PlSoloW(c)	CharTypeW(c, == SO, 0) | ||||||
|  |  | ||||||
|  | int | ||||||
|  | unicode_separator(pl_wchar_t c) | ||||||
|  | { return PlBlankW(c); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 		/******************************** | ||||||
|  | 		*           RAW READING         * | ||||||
|  | 		*********************************/ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||||||
|  | Scan the input, give prompts when necessary and return a char *  holding | ||||||
|  | a  stripped  version of the next term.  Contiguous white space is mapped | ||||||
|  | on a single space, block and % ... \n comment  is  deleted.   Memory  is | ||||||
|  | claimed automatically en enlarged if necessary. | ||||||
|  |  | ||||||
|  | (char *) NULL is returned on a syntax error. | ||||||
|  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | ||||||
|  |  | ||||||
|  | #define syntaxError(what, rd) { errorWarning(what, 0, rd); fail; } | ||||||
|  |  | ||||||
|  | static term_t | ||||||
|  | makeErrorTerm(const char *id_str, term_t id_term, ReadData _PL_rd) | ||||||
|  | { GET_LD | ||||||
|  |   term_t ex, loc=0;			/* keep compiler happy */ | ||||||
|  |   unsigned char const *s, *ll = NULL; | ||||||
|  |   int rc = TRUE; | ||||||
|  |  | ||||||
|  |   if ( !(ex = PL_new_term_ref()) || | ||||||
|  |        !(loc = PL_new_term_ref()) ) | ||||||
|  |     rc = FALSE; | ||||||
|  |  | ||||||
|  |   if ( rc && !id_term ) | ||||||
|  |   { if ( !(id_term=PL_new_term_ref()) || | ||||||
|  | 	 !PL_put_atom_chars(id_term, id_str) ) | ||||||
|  |       rc = FALSE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( rc ) | ||||||
|  |     rc = PL_unify_term(ex, | ||||||
|  | 		       PL_FUNCTOR, FUNCTOR_error2, | ||||||
|  | 		         PL_FUNCTOR, FUNCTOR_syntax_error1, | ||||||
|  | 		           PL_TERM, id_term, | ||||||
|  | 		         PL_TERM, loc); | ||||||
|  |  | ||||||
|  |   source_char_no += last_token_start - rdbase; | ||||||
|  |   for(s=rdbase; s<last_token_start; s++) | ||||||
|  |   { if ( *s == '\n' ) | ||||||
|  |     { source_line_no++; | ||||||
|  |       ll = s+1; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( ll ) | ||||||
|  |   { int lp = 0; | ||||||
|  |  | ||||||
|  |     for(s = ll; s<last_token_start; s++) | ||||||
|  |     { switch(*s) | ||||||
|  |       { case '\b': | ||||||
|  | 	  if ( lp > 0 ) lp--; | ||||||
|  | 	  break; | ||||||
|  | 	case '\t': | ||||||
|  | 	  lp |= 7; | ||||||
|  | 	default: | ||||||
|  | 	  lp++; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     source_line_pos = lp; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( rc ) | ||||||
|  |   { if ( ReadingSource )			/* reading a file */ | ||||||
|  |     { rc = PL_unify_term(loc, | ||||||
|  | 			 PL_FUNCTOR, FUNCTOR_file4, | ||||||
|  | 			   PL_ATOM, source_file_name, | ||||||
|  | 			   PL_INT, source_line_no, | ||||||
|  | 			   PL_INT, source_line_pos, | ||||||
|  | 			   PL_INT64, source_char_no); | ||||||
|  |     } else if ( isStringStream(rb.stream) ) | ||||||
|  |     { size_t pos; | ||||||
|  |  | ||||||
|  |       pos = utf8_strlen((char *)rdbase, last_token_start-rdbase); | ||||||
|  |  | ||||||
|  |       rc = PL_unify_term(loc, | ||||||
|  | 			 PL_FUNCTOR, FUNCTOR_string2, | ||||||
|  | 			   PL_UTF8_STRING, rdbase, | ||||||
|  | 			   PL_INT, (int)pos); | ||||||
|  |     } else				/* any stream */ | ||||||
|  |     { term_t stream; | ||||||
|  |  | ||||||
|  |       if ( !(stream=PL_new_term_ref()) || | ||||||
|  | 	   !PL_unify_stream_or_alias(stream, rb.stream) || | ||||||
|  | 	   !PL_unify_term(loc, | ||||||
|  | 			  PL_FUNCTOR, FUNCTOR_stream4, | ||||||
|  | 			    PL_TERM, stream, | ||||||
|  | 			    PL_INT, source_line_no, | ||||||
|  | 			    PL_INT, source_line_pos, | ||||||
|  | 			    PL_INT64, source_char_no) ) | ||||||
|  | 	rc = FALSE; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return (rc ? ex : (term_t)0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static bool | ||||||
|  | errorWarning(const char *id_str, term_t id_term, ReadData _PL_rd) | ||||||
|  | { GET_LD | ||||||
|  |   term_t ex; | ||||||
|  |  | ||||||
|  |   LD->exception.processing = TRUE;	/* allow using spare stack */ | ||||||
|  |  | ||||||
|  |   ex = makeErrorTerm(id_str, id_term, _PL_rd); | ||||||
|  |  | ||||||
|  |   if ( _PL_rd ) | ||||||
|  |   { _PL_rd->has_exception = TRUE; | ||||||
|  |     if ( ex ) | ||||||
|  |       PL_put_term(_PL_rd->exception, ex); | ||||||
|  |     else | ||||||
|  |       PL_put_term(_PL_rd->exception, exception_term); | ||||||
|  |   } else | ||||||
|  |   { if ( ex ) | ||||||
|  |       PL_raise_exception(ex); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   fail; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | clearBuffer(ReadData _PL_rd) | ||||||
|  | { if (rb.size == 0) | ||||||
|  |   { rb.base = rb.fast; | ||||||
|  |     rb.size = sizeof(rb.fast); | ||||||
|  |   } | ||||||
|  |   rb.end = rb.base + rb.size; | ||||||
|  |   rdbase = rb.here = rb.base; | ||||||
|  |  | ||||||
|  |   _PL_rd->posp = rdbase; | ||||||
|  |   _PL_rd->posi = 0; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | growToBuffer(int c, ReadData _PL_rd) | ||||||
|  | { if ( rb.base == rb.fast )		/* intptr_t clause: jump to use malloc() */ | ||||||
|  |   { rb.base = PL_malloc(FASTBUFFERSIZE * 2); | ||||||
|  |     memcpy(rb.base, rb.fast, FASTBUFFERSIZE); | ||||||
|  |   } else | ||||||
|  |     rb.base = PL_realloc(rb.base, rb.size*2); | ||||||
|  |  | ||||||
|  |   DEBUG(8, Sdprintf("Reallocated read buffer at %ld\n", (intptr_t) rb.base)); | ||||||
|  |   _PL_rd->posp = rdbase = rb.base; | ||||||
|  |   rb.here = rb.base + rb.size; | ||||||
|  |   rb.size *= 2; | ||||||
|  |   rb.end  = rb.base + rb.size; | ||||||
|  |   _PL_rd->posi = 0; | ||||||
|  |  | ||||||
|  |   *rb.here++ = c; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static inline void | ||||||
|  | addByteToBuffer(int c, ReadData _PL_rd) | ||||||
|  | { c &= 0xff; | ||||||
|  |  | ||||||
|  |   if ( rb.here >= rb.end ) | ||||||
|  |     growToBuffer(c, _PL_rd); | ||||||
|  |   else | ||||||
|  |     *rb.here++ = c; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | addToBuffer(int c, ReadData _PL_rd) | ||||||
|  | { if ( c <= 0x7f ) | ||||||
|  |   { addByteToBuffer(c, _PL_rd); | ||||||
|  |   } else | ||||||
|  |   { char buf[10]; | ||||||
|  |     char *s, *e; | ||||||
|  |  | ||||||
|  |     e = utf8_put_char(buf, c); | ||||||
|  |     for(s=buf; s<e; s++) | ||||||
|  |       addByteToBuffer(*s, _PL_rd); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | setCurrentSourceLocation(IOSTREAM *s ARG_LD) | ||||||
|  | { atom_t a; | ||||||
|  |  | ||||||
|  |   if ( s->position ) | ||||||
|  |   { source_line_no  = s->position->lineno; | ||||||
|  |     source_line_pos = s->position->linepos - 1;	/* char just read! */ | ||||||
|  |     source_char_no  = s->position->charno - 1;	/* char just read! */ | ||||||
|  |   } else | ||||||
|  |   { source_line_no  = -1; | ||||||
|  |     source_line_pos = -1; | ||||||
|  |     source_char_no  = 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( (a = fileNameStream(s)) ) | ||||||
|  |     source_file_name = a; | ||||||
|  |   else | ||||||
|  |     source_file_name = NULL_ATOM; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static inline int | ||||||
|  | getchr__(ReadData _PL_rd) | ||||||
|  | { int c = Sgetcode(rb.stream); | ||||||
|  |  | ||||||
|  |   if ( !_PL_rd->char_conversion_table || c < 0 || c >= 256 ) | ||||||
|  |     return c; | ||||||
|  |  | ||||||
|  |   return _PL_rd->char_conversion_table[c]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #define getchr()  getchr__(_PL_rd) | ||||||
|  | #define getchrq() Sgetcode(rb.stream) | ||||||
|  |  | ||||||
|  | #define ensure_space(c) { if ( something_read && \ | ||||||
|  | 			       (c == '\n' || !isBlank(rb.here[-1])) ) \ | ||||||
|  | 			   addToBuffer(c, _PL_rd); \ | ||||||
|  | 		        } | ||||||
|  | #define set_start_line { if ( !something_read ) \ | ||||||
|  | 			 { setCurrentSourceLocation(rb.stream PASS_LD); \ | ||||||
|  | 			   something_read++; \ | ||||||
|  | 			 } \ | ||||||
|  | 		       } | ||||||
|  |  | ||||||
|  | #define rawSyntaxError(what) { addToBuffer(EOS, _PL_rd); \ | ||||||
|  | 			       rdbase = rb.base, last_token_start = rb.here-1; \ | ||||||
|  | 			       syntaxError(what, _PL_rd); \ | ||||||
|  | 			     } | ||||||
|  |  | ||||||
|  | static int | ||||||
|  | raw_read_quoted(int q, ReadData _PL_rd) | ||||||
|  | { int newlines = 0; | ||||||
|  |   int c; | ||||||
|  |  | ||||||
|  |   addToBuffer(q, _PL_rd); | ||||||
|  |   while((c=getchrq()) != EOF && c != q) | ||||||
|  |   { if ( c == '\\' && DO_CHARESCAPE ) | ||||||
|  |     { int base; | ||||||
|  |  | ||||||
|  |       addToBuffer(c, _PL_rd); | ||||||
|  |  | ||||||
|  |       switch( (c=getchrq()) ) | ||||||
|  |       { case EOF: | ||||||
|  | 	  goto eofinstr; | ||||||
|  | 	case 'u':			/* \uXXXX */ | ||||||
|  | 	case 'U':			/* \UXXXXXXXX */ | ||||||
|  | 	  addToBuffer(c, _PL_rd); | ||||||
|  | 	  continue; | ||||||
|  | 	case 'x':			/* \xNN\ */ | ||||||
|  | 	  addToBuffer(c, _PL_rd); | ||||||
|  | 	  c = getchrq(); | ||||||
|  | 	  if ( c == EOF ) | ||||||
|  | 	    goto eofinstr; | ||||||
|  | 	  if ( digitValue(16, c) >= 0 ) | ||||||
|  | 	  { base = 16; | ||||||
|  | 	    addToBuffer(c, _PL_rd); | ||||||
|  |  | ||||||
|  | 	  xdigits: | ||||||
|  | 	    c = getchrq(); | ||||||
|  | 	    while( digitValue(base, c) >= 0 ) | ||||||
|  | 	    { addToBuffer(c, _PL_rd); | ||||||
|  | 	      c = getchrq(); | ||||||
|  | 	    } | ||||||
|  | 	  } | ||||||
|  | 	  if ( c == EOF ) | ||||||
|  | 	    goto eofinstr; | ||||||
|  | 	  addToBuffer(c, _PL_rd); | ||||||
|  | 	  if ( c == q ) | ||||||
|  | 	    return TRUE; | ||||||
|  | 	  continue; | ||||||
|  | 	default: | ||||||
|  | 	  addToBuffer(c, _PL_rd); | ||||||
|  | 	  if ( digitValue(8, c) >= 0 )	/* \NNN\ */ | ||||||
|  | 	  { base = 8; | ||||||
|  | 	    goto xdigits; | ||||||
|  | 	  } else if ( c == '\n' )	/* \<newline> */ | ||||||
|  | 	  { c = getchrq(); | ||||||
|  | 	    if ( c == EOF ) | ||||||
|  | 	      goto eofinstr; | ||||||
|  | 	    addToBuffer(c, _PL_rd); | ||||||
|  | 	    if ( c == q ) | ||||||
|  | 	      return TRUE; | ||||||
|  | 	  } | ||||||
|  | 	  continue;			/* \symbolic-control-char */ | ||||||
|  |       } | ||||||
|  |     } else if (c == '\n' && | ||||||
|  | 	       newlines++ > MAXNEWLINES && | ||||||
|  | 	       (_PL_rd->styleCheck & LONGATOM_CHECK)) | ||||||
|  |     { rawSyntaxError("long_string"); | ||||||
|  |     } | ||||||
|  |     addToBuffer(c, _PL_rd); | ||||||
|  |   } | ||||||
|  |   if (c == EOF) | ||||||
|  |   { eofinstr: | ||||||
|  |       rawSyntaxError("end_of_file_in_string"); | ||||||
|  |   } | ||||||
|  |   addToBuffer(c, _PL_rd); | ||||||
|  |  | ||||||
|  |   return TRUE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static int | ||||||
|  | add_comment(Buffer b, IOPOS *pos, ReadData _PL_rd ARG_LD) | ||||||
|  | { term_t head = PL_new_term_ref(); | ||||||
|  |  | ||||||
|  |   assert(_PL_rd->comments); | ||||||
|  |   if ( !PL_unify_list(_PL_rd->comments, head, _PL_rd->comments) ) | ||||||
|  |     return FALSE; | ||||||
|  |   if ( pos ) | ||||||
|  |   { if ( !PL_unify_term(head, | ||||||
|  | 			PL_FUNCTOR, FUNCTOR_minus2, | ||||||
|  | 			  PL_FUNCTOR, FUNCTOR_stream_position4, | ||||||
|  | 			    PL_INT64, pos->charno, | ||||||
|  | 			    PL_INT, pos->lineno, | ||||||
|  | 			    PL_INT, pos->linepos, | ||||||
|  | 			    PL_INT, 0, | ||||||
|  | 			  PL_UTF8_STRING, baseBuffer(b, char)) ) | ||||||
|  |       return FALSE; | ||||||
|  |   } else | ||||||
|  |   { if ( !PL_unify_term(head, | ||||||
|  | 			PL_FUNCTOR, FUNCTOR_minus2, | ||||||
|  | 			  ATOM_minus, | ||||||
|  | 			  PL_UTF8_STRING, baseBuffer(b, char)) ) | ||||||
|  |       return FALSE; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   PL_reset_term_refs(head); | ||||||
|  |   return TRUE; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static void | ||||||
|  | setErrorLocation(IOPOS *pos, ReadData _PL_rd) | ||||||
|  | { if ( pos ) | ||||||
|  |   { GET_LD | ||||||
|  |  | ||||||
|  |     source_char_no = pos->charno; | ||||||
|  |     source_line_pos = pos->linepos; | ||||||
|  |     source_line_no = pos->lineno; | ||||||
|  |   } | ||||||
|  |   rb.here = rb.base+1;			/* see rawSyntaxError() */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static unsigned char * | ||||||
|  | raw_read2(ReadData _PL_rd ARG_LD) | ||||||
|  | { int c; | ||||||
|  |   bool something_read = FALSE; | ||||||
|  |   bool dotseen = FALSE; | ||||||
|  |   IOPOS pbuf;					/* comment start */ | ||||||
|  |   IOPOS *pos; | ||||||
|  |  | ||||||
|  |   clearBuffer(_PL_rd);				/* clear input buffer */ | ||||||
|  |   _PL_rd->strictness = truePrologFlag(PLFLAG_ISO); | ||||||
|  |   source_line_no = -1; | ||||||
|  |  | ||||||
|  |   for(;;) | ||||||
|  |   { c = getchr(); | ||||||
|  |  | ||||||
|  |   handle_c: | ||||||
|  |     switch(c) | ||||||
|  |     { case EOF: | ||||||
|  | 		if ( isStringStream(rb.stream) ) /* do not require '. ' when */ | ||||||
|  | 		{ addToBuffer(' ', _PL_rd);     /* reading from a string */ | ||||||
|  | 		  addToBuffer('.', _PL_rd); | ||||||
|  | 		  addToBuffer(' ', _PL_rd); | ||||||
|  | 		  addToBuffer(EOS, _PL_rd); | ||||||
|  | 		  return rb.base; | ||||||
|  | 		} | ||||||
|  | 		if (something_read) | ||||||
|  | 		{ if ( dotseen )		/* term.<EOF> */ | ||||||
|  | 		  { if ( rb.here - rb.base == 1 ) | ||||||
|  | 		      rawSyntaxError("end_of_clause"); | ||||||
|  | 		    ensure_space(' '); | ||||||
|  | 		    addToBuffer(EOS, _PL_rd); | ||||||
|  | 		    return rb.base; | ||||||
|  | 		  } | ||||||
|  | 		  rawSyntaxError("end_of_file"); | ||||||
|  | 		} | ||||||
|  | 		if ( Sfpasteof(rb.stream) ) | ||||||
|  | 		{ term_t stream; | ||||||
|  |  | ||||||
|  | 		  LD->exception.processing = TRUE; | ||||||
|  | 		  stream = PL_new_term_ref(); | ||||||
|  | 		  PL_unify_stream_or_alias(stream, rb.stream); | ||||||
|  | 		  PL_error(NULL, 0, NULL, ERR_PERMISSION, | ||||||
|  | 			   ATOM_input, ATOM_past_end_of_stream, stream); | ||||||
|  | 		  return NULL; | ||||||
|  | 		} | ||||||
|  | 		set_start_line; | ||||||
|  | 		strcpy((char *)rb.base, "end_of_file. "); | ||||||
|  | 		rb.here = rb.base + 14; | ||||||
|  | 		return rb.base; | ||||||
|  |       case '/': if ( rb.stream->position ) | ||||||
|  | 		{ pbuf = *rb.stream->position; | ||||||
|  | 		  pbuf.charno--; | ||||||
|  | 		  pbuf.linepos--; | ||||||
|  | 		  pos = &pbuf; | ||||||
|  | 		} else | ||||||
|  | 		  pos = NULL; | ||||||
|  |  | ||||||
|  | 	        c = getchr(); | ||||||
|  | 		if ( c == '*' ) | ||||||
|  | 		{ int last; | ||||||
|  | 		  int level = 1; | ||||||
|  | 		  tmp_buffer ctmpbuf; | ||||||
|  | 		  Buffer cbuf; | ||||||
|  |  | ||||||
|  | 		  if ( _PL_rd->comments ) | ||||||
|  | 		  { initBuffer(&ctmpbuf); | ||||||
|  | 		    cbuf = (Buffer)&ctmpbuf; | ||||||
|  | 		    addUTF8Buffer(cbuf, '/'); | ||||||
|  | 		    addUTF8Buffer(cbuf, '*'); | ||||||
|  | 		  } else | ||||||
|  | 		  { cbuf = NULL; | ||||||
|  | 		  } | ||||||
|  |  | ||||||
|  | 		  if ((last = getchr()) == EOF) | ||||||
|  | 		  { if ( cbuf ) | ||||||
|  | 		      discardBuffer(cbuf); | ||||||
|  | 		    setErrorLocation(pos, _PL_rd); | ||||||
|  | 		    rawSyntaxError("end_of_file_in_block_comment"); | ||||||
|  | 		  } | ||||||
|  | 		  if ( cbuf ) | ||||||
|  | 		    addUTF8Buffer(cbuf, last); | ||||||
|  |  | ||||||
|  | 		  if ( something_read ) | ||||||
|  | 		  { addToBuffer(' ', _PL_rd);	/* positions */ | ||||||
|  | 		    addToBuffer(' ', _PL_rd); | ||||||
|  | 		    addToBuffer(last == '\n' ? last : ' ', _PL_rd); | ||||||
|  | 		  } | ||||||
|  |  | ||||||
|  | 		  for(;;) | ||||||
|  | 		  { c = getchr(); | ||||||
|  |  | ||||||
|  | 		    if ( cbuf ) | ||||||
|  | 		      addUTF8Buffer(cbuf, c); | ||||||
|  |  | ||||||
|  | 		    switch( c ) | ||||||
|  | 		    { case EOF: | ||||||
|  | 			if ( cbuf ) | ||||||
|  | 			  discardBuffer(cbuf); | ||||||
|  | 		        setErrorLocation(pos, _PL_rd); | ||||||
|  | 			rawSyntaxError("end_of_file_in_block_comment"); | ||||||
|  | 		      case '*': | ||||||
|  | 			if ( last == '/' ) | ||||||
|  | 			  level++; | ||||||
|  | 			break; | ||||||
|  | 		      case '/': | ||||||
|  | 			if ( last == '*' && | ||||||
|  | 			     (--level == 0 || _PL_rd->strictness) ) | ||||||
|  | 			{ if ( cbuf ) | ||||||
|  | 			  { addUTF8Buffer(cbuf, EOS); | ||||||
|  | 			    if ( !add_comment(cbuf, pos, _PL_rd PASS_LD) ) | ||||||
|  | 			    { discardBuffer(cbuf); | ||||||
|  | 			      return FALSE; | ||||||
|  | 			    } | ||||||
|  | 			    discardBuffer(cbuf); | ||||||
|  | 			  } | ||||||
|  | 			  c = ' '; | ||||||
|  | 			  goto handle_c; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		    } | ||||||
|  | 		    if ( something_read ) | ||||||
|  | 		      addToBuffer(c == '\n' ? c : ' ', _PL_rd); | ||||||
|  | 		    last = c; | ||||||
|  | 		  } | ||||||
|  | 		} else | ||||||
|  | 		{ set_start_line; | ||||||
|  | 		  addToBuffer('/', _PL_rd); | ||||||
|  | 		  if ( isSymbolW(c) ) | ||||||
|  | 		  { while( c != EOF && isSymbolW(c) && | ||||||
|  | 			   !(c == '`' && _PL_rd->backquoted_string) ) | ||||||
|  | 		    { addToBuffer(c, _PL_rd); | ||||||
|  | 		      c = getchr(); | ||||||
|  | 		    } | ||||||
|  | 		  } | ||||||
|  | 		  dotseen = FALSE; | ||||||
|  | 		  goto handle_c; | ||||||
|  | 		} | ||||||
|  |       case '%': if ( something_read ) | ||||||
|  | 		  addToBuffer(' ', _PL_rd); | ||||||
|  |       		if ( _PL_rd->comments ) | ||||||
|  | 		{ tmp_buffer ctmpbuf; | ||||||
|  | 		  Buffer cbuf; | ||||||
|  |  | ||||||
|  | 		  if ( rb.stream->position ) | ||||||
|  | 		  { pbuf = *rb.stream->position; | ||||||
|  | 		    pbuf.charno--; | ||||||
|  | 		    pbuf.linepos--; | ||||||
|  | 		    pos = &pbuf; | ||||||
|  | 		  } else | ||||||
|  | 		    pos = NULL; | ||||||
|  |  | ||||||
|  | 		  initBuffer(&ctmpbuf); | ||||||
|  | 		  cbuf = (Buffer)&ctmpbuf; | ||||||
|  | 		  addUTF8Buffer(cbuf, '%'); | ||||||
|  |  | ||||||
|  | 		  for(;;) | ||||||
|  | 		  { while((c=getchr()) != EOF && c != '\n') | ||||||
|  | 		    { addUTF8Buffer(cbuf, c); | ||||||
|  | 		      if ( something_read )		/* record positions */ | ||||||
|  | 			addToBuffer(' ', _PL_rd); | ||||||
|  | 		    } | ||||||
|  | 		    if ( c == '\n' ) | ||||||
|  | 		    { int c2 = Speekcode(rb.stream); | ||||||
|  |  | ||||||
|  | 		      if ( c2 == '%' ) | ||||||
|  | 		      { if ( something_read ) | ||||||
|  | 			{ addToBuffer(c, _PL_rd); | ||||||
|  | 			  addToBuffer(' ', _PL_rd); | ||||||
|  | 			} | ||||||
|  | 			addUTF8Buffer(cbuf, c); | ||||||
|  | 			c = Sgetcode(rb.stream); | ||||||
|  | 			assert(c==c2); | ||||||
|  | 			addUTF8Buffer(cbuf, c); | ||||||
|  | 			continue; | ||||||
|  | 		      } | ||||||
|  | 		    } | ||||||
|  | 		    break; | ||||||
|  | 		  } | ||||||
|  | 		  addUTF8Buffer(cbuf, EOS); | ||||||
|  | 		  if ( !add_comment(cbuf, pos, _PL_rd PASS_LD) ) | ||||||
|  | 		  { discardBuffer(cbuf); | ||||||
|  | 		    return FALSE; | ||||||
|  | 		  } | ||||||
|  | 		  discardBuffer(cbuf); | ||||||
|  | 		} else | ||||||
|  | 		{ while((c=getchr()) != EOF && c != '\n') | ||||||
|  | 		  { if ( something_read )		/* record positions */ | ||||||
|  | 		      addToBuffer(' ', _PL_rd); | ||||||
|  | 		  } | ||||||
|  | 		} | ||||||
|  | 		goto handle_c;		/* is the newline */ | ||||||
|  |      case '\'': if ( rb.here > rb.base && isDigit(rb.here[-1]) ) | ||||||
|  | 		{ cucharp bs = &rb.here[-1]; | ||||||
|  |  | ||||||
|  | 		  if ( bs > rb.base && isDigit(bs[-1]) ) | ||||||
|  | 		    bs--; | ||||||
|  | 		  if ( bs > rb.base && isSign(bs[-1]) ) | ||||||
|  | 		    bs--; | ||||||
|  |  | ||||||
|  | 		  if ( bs == rb.base || !PlIdContW(bs[-1]) ) | ||||||
|  | 		  { int base; | ||||||
|  |  | ||||||
|  | 		    if ( isSign(bs[0]) ) | ||||||
|  | 		      bs++; | ||||||
|  | 		    base = atoi((char*)bs); | ||||||
|  |  | ||||||
|  | 		    if ( base <= 36 ) | ||||||
|  | 		    { if ( base == 0 )			/* 0'<c> */ | ||||||
|  | 		      { addToBuffer(c, _PL_rd); | ||||||
|  | 			{ if ( (c=getchr()) != EOF ) | ||||||
|  | 			  { addToBuffer(c, _PL_rd); | ||||||
|  | 			    if ( c == '\\' ) 		/* 0'\<c> */ | ||||||
|  | 			    { if ( (c=getchr()) != EOF ) | ||||||
|  | 				addToBuffer(c, _PL_rd); | ||||||
|  | 			    } else if ( c == '\'' ) 	/* 0'' */ | ||||||
|  | 			    { if ( (c=getchr()) != EOF ) | ||||||
|  | 			      { if ( c == '\'' ) | ||||||
|  | 				  addToBuffer(c, _PL_rd); | ||||||
|  | 				else | ||||||
|  | 				  goto handle_c; | ||||||
|  | 			      } | ||||||
|  | 			    } | ||||||
|  | 			    break; | ||||||
|  | 			  } | ||||||
|  | 			  rawSyntaxError("end_of_file"); | ||||||
|  | 			} | ||||||
|  | 		      } else | ||||||
|  | 		      { int c2 = Speekcode(rb.stream); | ||||||
|  |  | ||||||
|  | 			if ( c2 != EOF ) | ||||||
|  | 			{ if ( digitValue(base, c2) >= 0 ) | ||||||
|  | 			  { addToBuffer(c, _PL_rd); | ||||||
|  | 			    c = Sgetcode(rb.stream); | ||||||
|  | 			    addToBuffer(c, _PL_rd); | ||||||
|  | 			    dotseen = FALSE; | ||||||
|  | 			    break; | ||||||
|  | 			  } | ||||||
|  | 			  goto sqatom; | ||||||
|  | 			} | ||||||
|  | 			rawSyntaxError("end_of_file"); | ||||||
|  | 		      } | ||||||
|  | 		    } | ||||||
|  | 		  } | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	      sqatom: | ||||||
|  |      		set_start_line; | ||||||
|  |      		if ( !raw_read_quoted(c, _PL_rd) ) | ||||||
|  | 		  fail; | ||||||
|  | 		dotseen = FALSE; | ||||||
|  | 		break; | ||||||
|  |       case '"':	set_start_line; | ||||||
|  |                 if ( !raw_read_quoted(c, _PL_rd) ) | ||||||
|  | 		  fail; | ||||||
|  | 		dotseen = FALSE; | ||||||
|  | 		break; | ||||||
|  |       case '.': addToBuffer(c, _PL_rd); | ||||||
|  | 		set_start_line; | ||||||
|  | 		dotseen++; | ||||||
|  | 		c = getchr(); | ||||||
|  | 		if ( isSymbolW(c) ) | ||||||
|  | 		{ while( c != EOF && isSymbolW(c) && | ||||||
|  | 			 !(c == '`' && _PL_rd->backquoted_string) ) | ||||||
|  | 		  { addToBuffer(c, _PL_rd); | ||||||
|  | 		    c = getchr(); | ||||||
|  | 		  } | ||||||
|  | 		  dotseen = FALSE; | ||||||
|  | 		} | ||||||
|  | 		goto handle_c; | ||||||
|  |       case '`': if ( _PL_rd->backquoted_string ) | ||||||
|  | 		{ set_start_line; | ||||||
|  | 		  if ( !raw_read_quoted(c, _PL_rd) ) | ||||||
|  | 		    fail; | ||||||
|  | 		  dotseen = FALSE; | ||||||
|  | 		  break; | ||||||
|  | 		} | ||||||
|  |       	        /*FALLTHROUGH*/ | ||||||
|  |       default:	if ( c < 0xff ) | ||||||
|  | 		{ switch(_PL_char_types[c]) | ||||||
|  | 		  { case SP: | ||||||
|  | 		    case CT: | ||||||
|  | 		    blank: | ||||||
|  | 		      if ( dotseen ) | ||||||
|  | 		      { if ( rb.here - rb.base == 1 ) | ||||||
|  | 			  rawSyntaxError("end_of_clause"); | ||||||
|  | 			ensure_space(c); | ||||||
|  | 			addToBuffer(EOS, _PL_rd); | ||||||
|  | 			return rb.base; | ||||||
|  | 		      } | ||||||
|  | 		      do | ||||||
|  | 		      { if ( something_read ) /* positions, \0 --> ' ' */ | ||||||
|  | 			  addToBuffer(c ? c : ' ', _PL_rd); | ||||||
|  | 			else | ||||||
|  | 			  ensure_space(c); | ||||||
|  | 			c = getchr(); | ||||||
|  | 		      } while( c != EOF && PlBlankW(c) ); | ||||||
|  | 		      goto handle_c; | ||||||
|  | 		    case SY: | ||||||
|  | 		      set_start_line; | ||||||
|  | 		      do | ||||||
|  | 		      { addToBuffer(c, _PL_rd); | ||||||
|  | 			c = getchr(); | ||||||
|  | 			if ( c == '`' && _PL_rd->backquoted_string ) | ||||||
|  | 			  break; | ||||||
|  | 		      } while( c != EOF && c <= 0xff && isSymbol(c) ); | ||||||
|  | 					/* TBD: wide symbols? */ | ||||||
|  | 		      dotseen = FALSE; | ||||||
|  | 		      goto handle_c; | ||||||
|  | 		    case LC: | ||||||
|  | 		    case UC: | ||||||
|  | 		      set_start_line; | ||||||
|  | 		      do | ||||||
|  | 		      { addToBuffer(c, _PL_rd); | ||||||
|  | 			c = getchr(); | ||||||
|  | 		      } while( c != EOF && PlIdContW(c) ); | ||||||
|  | 		      dotseen = FALSE; | ||||||
|  | 		      goto handle_c; | ||||||
|  | 		    default: | ||||||
|  | 		      addToBuffer(c, _PL_rd); | ||||||
|  | 		      dotseen = FALSE; | ||||||
|  | 		      set_start_line; | ||||||
|  | 		  } | ||||||
|  | 		} else			/* > 255 */ | ||||||
|  | 		{ if ( PlIdStartW(c) ) | ||||||
|  | 		  { set_start_line; | ||||||
|  | 		    do | ||||||
|  | 		    { addToBuffer(c, _PL_rd); | ||||||
|  | 		      c = getchr(); | ||||||
|  | 		    } while( c != EOF && PlIdContW(c) ); | ||||||
|  | 		    dotseen = FALSE; | ||||||
|  | 		    goto handle_c; | ||||||
|  | 		  } else if ( PlBlankW(c) ) | ||||||
|  | 		  { goto blank; | ||||||
|  | 		  } else | ||||||
|  | 		  { addToBuffer(c, _PL_rd); | ||||||
|  | 		    dotseen = FALSE; | ||||||
|  | 		    set_start_line; | ||||||
|  | 		  } | ||||||
|  | 		} | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||||||
|  | Raw reading returns a string in  UTF-8   notation  of the a Prolog term. | ||||||
|  | Comment inside the term is  replaced  by   spaces  or  newline to ensure | ||||||
|  | proper reconstruction of source locations. Comment   before  the term is | ||||||
|  | skipped. | ||||||
|  | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | ||||||
|  |  | ||||||
|  | static unsigned char * | ||||||
|  | raw_read(ReadData _PL_rd, unsigned char **endp ARG_LD) | ||||||
|  | { unsigned char *s; | ||||||
|  |  | ||||||
|  |   if ( (rb.stream->flags & SIO_ISATTY) && Sfileno(rb.stream) >= 0 ) | ||||||
|  |   { ttybuf tab; | ||||||
|  |  | ||||||
|  |     PushTty(rb.stream, &tab, TTY_SAVE);		/* make sure tty is sane */ | ||||||
|  |     PopTty(rb.stream, &ttytab, FALSE); | ||||||
|  |     s = raw_read2(_PL_rd PASS_LD); | ||||||
|  |     PopTty(rb.stream, &tab, TRUE); | ||||||
|  |   } else | ||||||
|  |   { s = raw_read2(_PL_rd PASS_LD); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if ( endp ) | ||||||
|  |     *endp = _PL_rd->_rb.here; | ||||||
|  |  | ||||||
|  |   return s; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		/******************************** | ||||||
|  | 		*       PROLOG CONNECTION       * | ||||||
|  | 		*********************************/ | ||||||
|  |  | ||||||
|  | static unsigned char * | ||||||
|  | backSkipUTF8(unsigned const char *start, unsigned const char *end, int *chr) | ||||||
|  | { const unsigned char *s; | ||||||
|  |  | ||||||
|  |   for(s=end-1 ; s>start && *s&0x80; s--) | ||||||
|  |     ; | ||||||
|  |   utf8_get_char((char*)s, chr); | ||||||
|  |  | ||||||
|  |   return (unsigned char *)s; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | static unsigned char * | ||||||
|  | backSkipBlanks(const unsigned char *start, const unsigned char *end) | ||||||
|  | { const unsigned char *s; | ||||||
|  |  | ||||||
|  |   for( ; end > start; end = s) | ||||||
|  |   { unsigned char *e; | ||||||
|  |     int chr; | ||||||
|  |  | ||||||
|  |     for(s=end-1 ; s>start && ISUTF8_CB(*s); s--) | ||||||
|  |       ; | ||||||
|  |     e = (unsigned char*)utf8_get_char((char*)s, &chr); | ||||||
|  |     assert(e == end); | ||||||
|  |     if ( !PlBlankW(chr) ) | ||||||
|  |       return (unsigned char*)end; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return (unsigned char *)start; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static inline ucharp | ||||||
|  | skipSpaces(cucharp in) | ||||||
|  | { int chr; | ||||||
|  |   ucharp s; | ||||||
|  |  | ||||||
|  |   for( ; *in; in=s) | ||||||
|  |   { s = utf8_get_uchar(in, &chr); | ||||||
|  |  | ||||||
|  |     if ( !PlBlankW(chr) ) | ||||||
|  |       return (ucharp)in; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return (ucharp)in; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | word | ||||||
|  | pl_raw_read2(term_t from, term_t term) | ||||||
|  | { GET_LD | ||||||
|  |   unsigned char *s, *e, *t2, *top; | ||||||
|  |   read_data rd; | ||||||
|  |   word rval; | ||||||
|  |   IOSTREAM *in; | ||||||
|  |   int chr; | ||||||
|  |   PL_chars_t txt; | ||||||
|  |  | ||||||
|  |   if ( !getInputStream(from, &in) ) | ||||||
|  |     fail; | ||||||
|  |  | ||||||
|  |   init_read_data(&rd, in PASS_LD); | ||||||
|  |   if ( !(s = raw_read(&rd, &e PASS_LD)) ) | ||||||
|  |   { rval = PL_raise_exception(rd.exception); | ||||||
|  |     goto out; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | 					/* strip the input from blanks */ | ||||||
|  |   top = backSkipBlanks(s, e-1); | ||||||
|  |   t2 = backSkipUTF8(s, top, &chr); | ||||||
|  |   if ( chr == '.' ) | ||||||
|  |     top = backSkipBlanks(s, t2); | ||||||
|  | 					/* watch for "0' ." */ | ||||||
|  |   if ( top < e && top-2 >= s && top[-1] == '\'' && top[-2] == '0' ) | ||||||
|  |     top++; | ||||||
|  |   *top = EOS; | ||||||
|  |   s = skipSpaces(s); | ||||||
|  |  | ||||||
|  |   txt.text.t    = (char*)s; | ||||||
|  |   txt.length    = top-s; | ||||||
|  |   txt.storage   = PL_CHARS_HEAP; | ||||||
|  |   txt.encoding  = ENC_UTF8; | ||||||
|  |   txt.canonical = FALSE; | ||||||
|  |  | ||||||
|  |   rval = PL_unify_text(term, 0, &txt, PL_ATOM); | ||||||
|  |  | ||||||
|  | out: | ||||||
|  |   free_read_data(&rd); | ||||||
|  |   if ( Sferror(in) ) | ||||||
|  |     return streamStatus(in); | ||||||
|  |   else | ||||||
|  |     PL_release_stream(in); | ||||||
|  |  | ||||||
|  |   return rval; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | word | ||||||
|  | pl_raw_read(term_t term) | ||||||
|  | { return pl_raw_read2(0, term); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| 		 /******************************* | 		 /******************************* | ||||||
| 		 *	   TERM <->ATOM		* | 		 *	   TERM <->ATOM		* | ||||||
| 		 *******************************/ | 		 *******************************/ | ||||||
|   | |||||||
| @@ -78,6 +78,9 @@ SWI-Prolog.h and SWI-Stream.h | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #undef ESC				/* will be redefined ... */ | #undef ESC				/* will be redefined ... */ | ||||||
|  | #ifdef META | ||||||
|  | #undef META /* conflict with macports readline */ | ||||||
|  | #endif | ||||||
| #include <stdio.h>			/* readline needs it */ | #include <stdio.h>			/* readline needs it */ | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| #define savestring(x)			/* avoid definition there */ | #define savestring(x)			/* avoid definition there */ | ||||||
| @@ -86,7 +89,7 @@ extern int rl_done;			/* should be in readline.h, but */ | |||||||
| 					/* isn't in some versions ... */ | 					/* isn't in some versions ... */ | ||||||
| #ifdef HAVE_READLINE_HISTORY_H | #ifdef HAVE_READLINE_HISTORY_H | ||||||
| #include <readline/history.h> | #include <readline/history.h> | ||||||
| #elif !defined(__APPLE__) | #else | ||||||
| extern void add_history(char *);	/* should be in readline.h */ | extern void add_history(char *);	/* should be in readline.h */ | ||||||
| #endif | #endif | ||||||
| 					/* missing prototypes in older */ | 					/* missing prototypes in older */ | ||||||
| @@ -94,6 +97,7 @@ extern void add_history(char *);	/* should be in readline.h */ | |||||||
| extern int rl_begin_undo_group(void);	/* delete when conflict arrises! */ | extern int rl_begin_undo_group(void);	/* delete when conflict arrises! */ | ||||||
| extern int rl_end_undo_group(void); | extern int rl_end_undo_group(void); | ||||||
| extern Function *rl_event_hook; | extern Function *rl_event_hook; | ||||||
|  |  | ||||||
| #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION | #ifndef HAVE_RL_FILENAME_COMPLETION_FUNCTION | ||||||
| #define rl_filename_completion_function filename_completion_function | #define rl_filename_completion_function filename_completion_function | ||||||
| extern char *filename_completion_function(const char *, int); | extern char *filename_completion_function(const char *, int); | ||||||
| @@ -335,7 +339,7 @@ rl_sighandler(int sig) | |||||||
|  |  | ||||||
|   DEBUG(3, Sdprintf("Resetting after signal\n")); |   DEBUG(3, Sdprintf("Resetting after signal\n")); | ||||||
|   prepare_signals(); |   prepare_signals(); | ||||||
| #ifndef __APPLE__ | #ifdef HAVE_RL_RESET_AFTER_SIGNAL | ||||||
|   rl_reset_after_signal (); |   rl_reset_after_signal (); | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| @@ -361,7 +365,7 @@ reentrant access is tried. | |||||||
|  |  | ||||||
| #ifdef HAVE_RL_EVENT_HOOK | #ifdef HAVE_RL_EVENT_HOOK | ||||||
| static int | static int | ||||||
| event_hook() | event_hook(void) | ||||||
| { if ( Sinput->position ) | { if ( Sinput->position ) | ||||||
|   { int64_t c0 = Sinput->position->charno; |   { int64_t c0 = Sinput->position->charno; | ||||||
|  |  | ||||||
| @@ -469,7 +473,7 @@ Sread_readline(void *handle, char *buf, size_t size) | |||||||
| 	{ int state = rl_readline_state; | 	{ int state = rl_readline_state; | ||||||
|  |  | ||||||
| 	  rl_clear_pending_input(); | 	  rl_clear_pending_input(); | ||||||
| #ifndef __APPLE__ | #ifdef HAVE_RL_DISCARD_ARGUMENT | ||||||
| 	  rl_discard_argument(); | 	  rl_discard_argument(); | ||||||
| #endif | #endif | ||||||
| 	  rl_deprep_terminal(); | 	  rl_deprep_terminal(); | ||||||
| @@ -516,7 +520,6 @@ Sread_readline(void *handle, char *buf, size_t size) | |||||||
| static int | static int | ||||||
| prolog_complete(int ignore, int key) | prolog_complete(int ignore, int key) | ||||||
| {  | {  | ||||||
| #ifndef __APPLE__ |  | ||||||
|   if ( rl_point > 0 && rl_line_buffer[rl_point-1] != ' ' ) |   if ( rl_point > 0 && rl_line_buffer[rl_point-1] != ' ' ) | ||||||
|     { rl_begin_undo_group(); |     { rl_begin_undo_group(); | ||||||
|       rl_complete(ignore, key); |       rl_complete(ignore, key); | ||||||
| @@ -532,7 +535,6 @@ prolog_complete(int ignore, int key) | |||||||
|       rl_end_undo_group(); |       rl_end_undo_group(); | ||||||
|     } else |     } else | ||||||
|     rl_complete(ignore, key); |     rl_complete(ignore, key); | ||||||
| #endif |  | ||||||
|  |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1622,7 +1622,7 @@ static const char* const uflags_map[UNICODE_MAP_SIZE] = | |||||||
|      F(0),    F(3), ucp0xfa, ucp0xfb,    F(3), ucp0xfd, ucp0xfe, ucp0xff |      F(0),    F(3), ucp0xfa, ucp0xfb,    F(3), ucp0xfd, ucp0xfe, ucp0xff | ||||||
| }; | }; | ||||||
|  |  | ||||||
| int | static int | ||||||
| uflagsW(int code) | uflagsW(int code) | ||||||
| { int cp = (unsigned)code / 256; | { int cp = (unsigned)code / 256; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -52,7 +52,6 @@ otherwise. | |||||||
|  |  | ||||||
| :- compile_expressions. | :- compile_expressions. | ||||||
|  |  | ||||||
|  |  | ||||||
| :- [ | :- [ | ||||||
|     % lists is often used. |     % lists is often used. | ||||||
|    	 'lists.yap', |    	 'lists.yap', | ||||||
| @@ -207,3 +206,4 @@ file_search_path(system, Dir) :- | |||||||
| file_search_path(foreign, yap('lib/Yap')). | file_search_path(foreign, yap('lib/Yap')). | ||||||
|  |  | ||||||
| :- yap_flag(unknown,error).  | :- yap_flag(unknown,error).  | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user