| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "pl-ctype.h"
 | 
					
						
							|  |  |  | #include "pl-dtoa.h"
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | #include "pl-incl.h"
 | 
					
						
							|  |  |  | #include "pl-umap.c" /* Unicode map */
 | 
					
						
							|  |  |  | #include "pl-utf8.h"
 | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | #include "pl-read.h" /* read structure */
 | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  *  @defgroup ReadTerm Read Term from Streams | 
					
						
							|  |  |  |  *  @ingroup  InputOutput | 
					
						
							|  |  |  |  * @{ | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static bool isStringStream(IOSTREAM *s) { | 
					
						
							|  |  |  |   return s->functions == &Sstringfunctions; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | void init_read_data(ReadData _PL_rd, IOSTREAM *in ARG_LD) { | 
					
						
							|  |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   memset(_PL_rd, 0, sizeof(*_PL_rd)); /* optimise! */ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   _PL_rd->magic = RD_MAGIC; | 
					
						
							|  |  |  |   _PL_rd->varnames = 0; | 
					
						
							|  |  |  |   _PL_rd->module = Yap_GetModuleEntry(CurrentModule); | 
					
						
							|  |  |  |   _PL_rd->exception = 0; | 
					
						
							|  |  |  |   _PL_rd->stream = in; | 
					
						
							|  |  |  |   _PL_rd->has_exception = 0; | 
					
						
							|  |  |  |   _PL_rd->module = MODULE_parse; | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   _PL_rd->flags = _PL_rd->module->flags; /* change for options! */ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   _PL_rd->styleCheck = LOCAL_debugstatus.styleCheck; | 
					
						
							|  |  |  |   _PL_rd->on_error = AtomError; | 
					
						
							|  |  |  |   _PL_rd->backquoted_string = truePrologFlag(PLFLAG_BACKQUOTED_STRING); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | void free_read_data(ReadData _PL_rd) {} | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static int read_term(term_t t, ReadData _PL_rd ARG_LD) { | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   return Yap_read_term(t, rb.stream, _PL_rd); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static void addUTF8Buffer(Buffer b, int c); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static void addUTF8Buffer(Buffer b, int c) { | 
					
						
							|  |  |  |   if (c >= 0x80) { | 
					
						
							|  |  |  |     char buf[6]; | 
					
						
							|  |  |  |     char *p, *end; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     end = utf8_put_char(buf, c); | 
					
						
							|  |  |  |     for (p = buf; p < end; p++) { | 
					
						
							|  |  |  |       addBuffer(b, *p & 0xff, char); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   } else { | 
					
						
							|  |  |  |     addBuffer(b, c, char); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************
 | 
					
						
							|  |  |  |  *     UNICODE CLASSIFIERS      * | 
					
						
							|  |  |  |  *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | #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, U_SYMBOL)
 | 
					
						
							|  |  |  | #define PlPunctW(c) CharTypeW(c, == PU, 0)
 | 
					
						
							|  |  |  | #define PlSoloW(c) CharTypeW(c, == SO, U_OTHER)
 | 
					
						
							|  |  |  | #define PlInvalidW(c) (uflagsW(c) == 0)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int f_is_prolog_var_start(wint_t c) { | 
					
						
							|  |  |  |   return PlIdStartW(c) && (PlUpperW(c) || c == '_'); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | int f_is_prolog_atom_start(wint_t c) { return PlIdStartW(c) != 0; } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | int f_is_prolog_identifier_continue(wint_t c) { | 
					
						
							|  |  |  |   return PlIdContW(c) || c == '_'; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | int f_is_prolog_symbol(wint_t c) { return PlSymbolW(c) != 0; } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | int unicode_separator(pl_wchar_t c) { return PlBlankW(c); } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  |    FALSE	return false | 
					
						
							|  |  |  |    TRUE	redo | 
					
						
							|  |  |  |    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static int reportReadError(ReadData rd) { | 
					
						
							|  |  |  |   if (rd->on_error == ATOM_error) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     return PL_raise_exception(rd->exception); | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (rd->on_error != ATOM_quiet) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     printMessage(ATOM_error, PL_TERM, rd->exception); | 
					
						
							|  |  |  |   PL_clear_exception(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (rd->on_error == ATOM_dec10) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     return TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* static int */ | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | /* reportSingletons(ReadData rd, singletons, Atom amod, Atom aname, UInt arity)
 | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | /* {  */ | 
					
						
							|  |  |  | /*   printMessage(ATOM_warning, PL_FUNCTOR_CHARS,  */ | 
					
						
							|  |  |  | /* 	       "singletons", 2, */ | 
					
						
							|  |  |  | /* 	       PL_TERM, singletons,  */ | 
					
						
							|  |  |  | /* 	       PL_TERM, mod, */ | 
					
						
							|  |  |  | /* 	       PL_FUNCTOR_divide2, */ | 
					
						
							|  |  |  | /* 	       PL_ATOM, name, */ | 
					
						
							|  |  |  | /* 	       PL_INT, arity); */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*   return FALSE; */ | 
					
						
							|  |  |  | /* } */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************
 | 
					
						
							|  |  |  |  *           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. | 
					
						
							|  |  |  |    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | #define syntaxError(what, rd)                                                  \
 | 
					
						
							|  |  |  |   {                                                                            \ | 
					
						
							|  |  |  |     errorWarning(what, 0, rd);                                                 \ | 
					
						
							|  |  |  |     fail;                                                                      \ | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | 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 */ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   unsigned char const *s, *ll = NULL; | 
					
						
							|  |  |  |   int rc = TRUE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (!(ex = PL_new_term_ref()) || !(loc = PL_new_term_ref())) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     rc = FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (rc && !id_term) { | 
					
						
							|  |  |  |     if (!(id_term = PL_new_term_ref()) || !PL_put_atom_chars(id_term, id_str)) | 
					
						
							|  |  |  |       rc = FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (rc) | 
					
						
							|  |  |  |     rc = PL_unify_term(ex, PL_FUNCTOR, FUNCTOR_error2, PL_FUNCTOR, | 
					
						
							|  |  |  |                        FUNCTOR_syntax_error1, PL_TERM, id_term, PL_TERM, loc); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   source_char_no += last_token_start - rdbase; | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   for (s = rdbase; s < last_token_start; s++) { | 
					
						
							|  |  |  |     if (*s == '\n') { | 
					
						
							|  |  |  |       source_line_no++; | 
					
						
							|  |  |  |       ll = s + 1; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   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++; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     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; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return (rc ? ex : (term_t)0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static bool errorWarning(const char *id_str, term_t id_term, ReadData _PL_rd) { | 
					
						
							|  |  |  |   GET_LD | 
					
						
							|  |  |  |   term_t ex; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   LD->exception.processing = TRUE; /* allow using spare stack */ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   ex = makeErrorTerm(id_str, id_term, _PL_rd); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   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); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   fail; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static void clearBuffer(ReadData _PL_rd) { | 
					
						
							|  |  |  |   if (rb.size == 0) { | 
					
						
							|  |  |  |     rb.base = rb.fast; | 
					
						
							|  |  |  |     rb.size = sizeof(rb.fast); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   rb.end = rb.base + rb.size; | 
					
						
							|  |  |  |   rdbase = rb.here = rb.base; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   _PL_rd->posp = rdbase; | 
					
						
							|  |  |  |   _PL_rd->posi = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | 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); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   DEBUG(8, Sdprintf("Reallocated read buffer at %ld\n", (intptr_t)rb.base)); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   _PL_rd->posp = rdbase = rb.base; | 
					
						
							|  |  |  |   rb.here = rb.base + rb.size; | 
					
						
							|  |  |  |   rb.size *= 2; | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   rb.end = rb.base + rb.size; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   _PL_rd->posi = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   *rb.here++ = c; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static inline void addByteToBuffer(int c, ReadData _PL_rd) { | 
					
						
							|  |  |  |   c &= 0xff; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (rb.here >= rb.end) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     growToBuffer(c, _PL_rd); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     *rb.here++ = c; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static void addToBuffer(int c, ReadData _PL_rd) { | 
					
						
							|  |  |  |   if (c <= 0x7f) { | 
					
						
							|  |  |  |     addByteToBuffer(c, _PL_rd); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     char buf[10]; | 
					
						
							|  |  |  |     char *s, *e; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     e = utf8_put_char(buf, c); | 
					
						
							|  |  |  |     for (s = buf; s < e; s++) | 
					
						
							|  |  |  |       addByteToBuffer(*s, _PL_rd); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if __YAP_PROLOG__
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | void Yap_setCurrentSourceLocation(void *rd) { | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   GET_LD | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   setCurrentSourceLocation(rd PASS_LD); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static inline int getchr__(ReadData _PL_rd) { | 
					
						
							|  |  |  |   int c = Sgetcode(rb.stream); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (!_PL_rd->char_conversion_table || c < 0 || c >= 256) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     return c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return _PL_rd->char_conversion_table[c]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | #define getchr() getchr__(_PL_rd)
 | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #define getchrq() Sgetcode(rb.stream)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | #define ensure_space(c)                                                        \
 | 
					
						
							|  |  |  |   {                                                                            \ | 
					
						
							|  |  |  |     if (something_read && (c == '\n' || !isBlank(rb.here[-1])))                \ | 
					
						
							|  |  |  |       addToBuffer(c, _PL_rd);                                                  \ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | #define set_start_line                                                         \
 | 
					
						
							|  |  |  |   {                                                                            \ | 
					
						
							|  |  |  |     if (!something_read) {                                                     \ | 
					
						
							|  |  |  |       setCurrentSourceLocation(_PL_rd PASS_LD);                                \ | 
					
						
							|  |  |  |       something_read++;                                                        \ | 
					
						
							|  |  |  |     }                                                                          \ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef O_QUASIQUOTATIONS
 | 
					
						
							|  |  |  | /** '$qq_open'(+QQRange, -Stream) is det.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Opens a quasi-quoted memory range. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @arg QQRange is a term '$quasi_quotation'(ReadData, Start, Length) | 
					
						
							|  |  |  |     @arg Stream  is a UTF-8 encoded string, whose position indication | 
					
						
							|  |  |  |     reflects the location in the real file. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static PRED_IMPL("$qq_open", 2, qq_open, 0) { | 
					
						
							|  |  |  |   PRED_LD | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (PL_is_functor(A1, FUNCTOR_dquasi_quotation3)) { | 
					
						
							|  |  |  |     void *ptr; | 
					
						
							|  |  |  |     char *start; | 
					
						
							|  |  |  |     size_t len; | 
					
						
							|  |  |  |     term_t arg = PL_new_term_ref(); | 
					
						
							|  |  |  |     IOSTREAM *s; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (PL_get_arg(1, A1, arg) && PL_get_pointer_ex(arg, &ptr) && | 
					
						
							|  |  |  |         PL_get_arg(2, A1, arg) && PL_get_intptr(arg, (intptr_t *)&start) && | 
					
						
							|  |  |  |         PL_get_arg(3, A1, arg) && | 
					
						
							|  |  |  |         PL_get_intptr(arg, (intptr_t *)&len)) { // source_location pos;
 | 
					
						
							|  |  |  |       if ((s = Sopenmem(&start, &len, "r"))) | 
					
						
							|  |  |  |         s->encoding = ENC_UTF8; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return PL_unify_stream(A2, s); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else | 
					
						
							|  |  |  |     PL_type_error("read_context", A1); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static int parse_quasi_quotations(ReadData _PL_rd ARG_LD) { | 
					
						
							|  |  |  |   if (_PL_rd->qq_tail) { | 
					
						
							|  |  |  |     term_t av; | 
					
						
							|  |  |  |     int rc; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     if (!PL_unify_nil(_PL_rd->qq_tail)) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     if (!_PL_rd->quasi_quotations) { | 
					
						
							|  |  |  |       if ((av = PL_new_term_refs(2)) && PL_put_term(av + 0, _PL_rd->qq) && | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #if __YAP_PROLOG__
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |           PL_put_atom(av + 1, YAP_SWIAtomFromAtom(_PL_rd->module->AtomOfME)) && | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |           PL_put_atom(av + 1, _PL_rd->module->name) && | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |           PL_cons_functor_v(av, FUNCTOR_dparse_quasi_quotations2, av)) { | 
					
						
							|  |  |  |         term_t ex; | 
					
						
							|  |  |  |         rc = callProlog(MODULE_system, av + 0, PL_Q_CATCH_EXCEPTION, &ex); | 
					
						
							|  |  |  |         if (rc) | 
					
						
							|  |  |  |           return TRUE; | 
					
						
							|  |  |  |         _PL_rd->exception = ex; | 
					
						
							|  |  |  |         _PL_rd->has_exception = TRUE; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     } else | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |       return TRUE; | 
					
						
							|  |  |  |   } else if (_PL_rd->quasi_quotations) /* user option, but no quotes */ | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     return PL_unify_nil(_PL_rd->quasi_quotations); | 
					
						
							|  |  |  |   } else | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /*O_QUASIQUOTATIONS*/
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | #define rawSyntaxError(what)                                                   \
 | 
					
						
							|  |  |  |   {                                                                            \ | 
					
						
							|  |  |  |     addToBuffer(EOS, _PL_rd);                                                  \ | 
					
						
							|  |  |  |     rdbase = rb.base, last_token_start = rb.here - 1;                          \ | 
					
						
							|  |  |  |     syntaxError(what, _PL_rd);                                                 \ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static int raw_read_quoted(int q, ReadData _PL_rd) { | 
					
						
							|  |  |  |   int newlines = 0; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   int c; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   addToBuffer(q, _PL_rd); | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   while ((c = getchrq()) != EOF && c != q) { | 
					
						
							|  |  |  |     if (c == '\\' && DO_CHARESCAPE) { | 
					
						
							|  |  |  |       int base; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |       addToBuffer(c, _PL_rd); | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |       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"); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     addToBuffer(c, _PL_rd); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (c == EOF) { | 
					
						
							|  |  |  |   eofinstr: | 
					
						
							|  |  |  |     rawSyntaxError("end_of_file_in_string"); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   addToBuffer(c, _PL_rd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static int add_comment(Buffer b, IOPOS *pos, ReadData _PL_rd ARG_LD) { | 
					
						
							|  |  |  |   term_t head = PL_new_term_ref(); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   assert(_PL_rd->comments); | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (!PL_unify_list(_PL_rd->comments, head, _PL_rd->comments)) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   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; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   PL_reset_term_refs(head); | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static void setErrorLocation(IOPOS *pos, ReadData _PL_rd) { | 
					
						
							|  |  |  |   if (pos) { | 
					
						
							|  |  |  |     GET_LD | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     source_char_no = pos->charno; | 
					
						
							|  |  |  |     source_line_pos = pos->linepos; | 
					
						
							|  |  |  |     source_line_no = pos->lineno; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   rb.here = rb.base + 1; /* see rawSyntaxError() */ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static unsigned char *raw_read2(ReadData _PL_rd ARG_LD) { | 
					
						
							|  |  |  |   int c; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   bool something_read = FALSE; | 
					
						
							|  |  |  |   bool dotseen = FALSE; | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   IOPOS pbuf; /* comment start */ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   IOPOS *pos; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   clearBuffer(_PL_rd); /* clear input buffer */ | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   _PL_rd->strictness = truePrologFlag(PLFLAG_ISO); | 
					
						
							|  |  |  |   source_line_no = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   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; | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |           tmp_buffer ctmpbuf; | 
					
						
							|  |  |  |           buffer tmpbuf; | 
					
						
							|  |  |  |         } u; | 
					
						
							|  |  |  |         Buffer cbuf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (_PL_rd->comments) { | 
					
						
							|  |  |  |           initBuffer(&u.ctmpbuf); | 
					
						
							|  |  |  |           cbuf = &u.tmpbuf; | 
					
						
							|  |  |  |           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"); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #ifndef __YAP_PROLOG__
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |           /* YAP does not support comment levels in original scanner */ | 
					
						
							|  |  |  |           case '*': | 
					
						
							|  |  |  |             if (last == '/') | 
					
						
							|  |  |  |               level++; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |           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) { | 
					
						
							|  |  |  |         union { | 
					
						
							|  |  |  |           tmp_buffer ctmpbuf; | 
					
						
							|  |  |  |           buffer uctmpbuf; | 
					
						
							|  |  |  |         } u; | 
					
						
							|  |  |  |         Buffer cbuf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (rb.stream->position) { | 
					
						
							|  |  |  |           pbuf = *rb.stream->position; | 
					
						
							|  |  |  |           pbuf.charno--; | 
					
						
							|  |  |  |           pbuf.linepos--; | 
					
						
							|  |  |  |           pos = &pbuf; | 
					
						
							|  |  |  |         } else | 
					
						
							|  |  |  |           pos = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         initBuffer(&u.ctmpbuf); | 
					
						
							|  |  |  |         cbuf = (Buffer)&u.uctmpbuf; | 
					
						
							|  |  |  |         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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | 
					
						
							|  |  |  |    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. | 
					
						
							|  |  |  |    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static unsigned char *raw_read(ReadData _PL_rd, unsigned char **endp ARG_LD) { | 
					
						
							|  |  |  |   unsigned char *s; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if ((rb.stream->flags & SIO_ISATTY) && Sfileno(rb.stream) >= 0) { | 
					
						
							|  |  |  |     ttybuf tab; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     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); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (endp) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     *endp = _PL_rd->_rb.here; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static void callCommentHook(term_t comments, term_t tpos, term_t term) { | 
					
						
							|  |  |  |   GET_LD | 
					
						
							|  |  |  |   fid_t fid; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   term_t av; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if ((fid = PL_open_foreign_frame()) && (av = PL_new_term_refs(3))) { | 
					
						
							|  |  |  |     qid_t qid; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     PL_put_term(av + 0, comments); | 
					
						
							|  |  |  |     PL_put_term(av + 1, tpos); | 
					
						
							|  |  |  |     PL_put_term(av + 2, term); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     if ((qid = PL_open_query(NULL, PL_Q_NODEBUG | PL_Q_CATCH_EXCEPTION, | 
					
						
							|  |  |  |                              (predicate_t)PredCommentHook, av))) { | 
					
						
							|  |  |  |       term_t ex; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |       if (!PL_next_solution(qid) && (ex = PL_exception(qid))) | 
					
						
							|  |  |  |         printMessage(ATOM_error, PL_TERM, ex); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |       PL_close_query(qid); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     PL_discard_foreign_frame(fid); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************
 | 
					
						
							|  |  |  |  *       PROLOG CONNECTION       * | 
					
						
							|  |  |  |  *********************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static unsigned char *backSkipUTF8(unsigned const char *start, | 
					
						
							|  |  |  |                                    unsigned const char *end, int *chr) { | 
					
						
							|  |  |  |   const unsigned char *s; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   for (s = end - 1; s > start && (*s & 0x80); s--) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     ; | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   utf8_get_char((char *)s, chr); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return (unsigned char *)s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static unsigned char *backSkipBlanks(const unsigned char *start, | 
					
						
							|  |  |  |                                      const unsigned char *end) { | 
					
						
							|  |  |  |   const unsigned char *s; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   for (; end > start; end = s) { | 
					
						
							|  |  |  |     unsigned char *e; | 
					
						
							|  |  |  |     int chr; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     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; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return (unsigned char *)start; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static inline ucharp skipSpaces(cucharp in) { | 
					
						
							|  |  |  |   int chr; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   ucharp s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   for (; *in; in = s) { | 
					
						
							|  |  |  |     s = utf8_get_uchar(in, &chr); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     if (!PlBlankW(chr)) | 
					
						
							|  |  |  |       return (ucharp)in; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return (ucharp)in; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | word pl_raw_read2(term_t from, term_t term) { | 
					
						
							|  |  |  |   GET_LD | 
					
						
							|  |  |  |   unsigned char *s, *e, *t2, *top; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   read_data rd; | 
					
						
							|  |  |  |   word rval; | 
					
						
							|  |  |  |   IOSTREAM *in; | 
					
						
							|  |  |  |   int chr; | 
					
						
							|  |  |  |   PL_chars_t txt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (!getTextInputStream(from, &in)) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     fail; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   init_read_data(&rd, in PASS_LD); | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (!(s = raw_read(&rd, &e PASS_LD))) { | 
					
						
							|  |  |  |     rval = PL_raise_exception(rd.exception); | 
					
						
							|  |  |  |     goto out; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /* strip the input from blanks */ | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   top = backSkipBlanks(s, e - 1); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   t2 = backSkipUTF8(s, top, &chr); | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (chr == '.') | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     top = backSkipBlanks(s, t2); | 
					
						
							|  |  |  |   /* watch for "0' ." */ | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (top < e && top - 2 >= s && top[-1] == '\'' && top[-2] == '0') | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     top++; | 
					
						
							|  |  |  |   *top = EOS; | 
					
						
							|  |  |  |   s = skipSpaces(s); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   txt.text.t = (char *)s; | 
					
						
							|  |  |  |   txt.length = top - s; | 
					
						
							|  |  |  |   txt.storage = PL_CHARS_HEAP; | 
					
						
							|  |  |  |   txt.encoding = ENC_UTF8; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   txt.canonical = FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   rval = PL_unify_text(term, 0, &txt, PL_ATOM); | 
					
						
							|  |  |  |   LD->read_varnames = rd.varnames; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | out: | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   free_read_data(&rd); | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (Sferror(in)) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     return streamStatus(in); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     PL_release_stream(in); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return rval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static int unify_read_term_position(term_t tpos ARG_LD) { | 
					
						
							|  |  |  |   if (tpos && source_line_no > 0) { | 
					
						
							|  |  |  |     return PL_unify_term(tpos, PL_FUNCTOR, FUNCTOR_stream_position4, PL_INT64, | 
					
						
							|  |  |  |                          source_char_no, PL_INT, source_line_no, PL_INT, | 
					
						
							|  |  |  |                          source_line_pos, PL_INT64, source_byte_no); | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     return TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static const opt_spec read_clause_options[] = { | 
					
						
							|  |  |  |     {ATOM_variable_names, OPT_TERM}, | 
					
						
							|  |  |  |     {ATOM_term_position, OPT_TERM}, | 
					
						
							|  |  |  |     {ATOM_subterm_positions, OPT_TERM}, | 
					
						
							|  |  |  |     {ATOM_process_comment, OPT_BOOL}, | 
					
						
							|  |  |  |     {ATOM_comments, OPT_TERM}, | 
					
						
							|  |  |  |     {ATOM_syntax_errors, OPT_ATOM}, | 
					
						
							|  |  |  |     {NULL_ATOM, 0}}; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** read_clause(+Stream:stream, -Clause:clause, +Options:list)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Like read_term/3, but uses current compiler options. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Options: | 
					
						
							|  |  |  |     * variable_names(-Names) | 
					
						
							|  |  |  |     * process_comment(+Boolean) | 
					
						
							|  |  |  |     * comments(-List) | 
					
						
							|  |  |  |     * syntax_errors(+Atom) | 
					
						
							|  |  |  |     * term_position(-Position) | 
					
						
							|  |  |  |     * subterm_positions(-Layout) | 
					
						
							|  |  |  |     */ | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static int read_clause(IOSTREAM *s, term_t term, term_t options ARG_LD) { | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   read_data rd; | 
					
						
							|  |  |  |   int rval; | 
					
						
							|  |  |  |   fid_t fid; | 
					
						
							|  |  |  |   term_t tpos = 0; | 
					
						
							|  |  |  |   term_t comments = 0; | 
					
						
							|  |  |  |   term_t opt_comments = 0; | 
					
						
							|  |  |  |   int process_comment; | 
					
						
							|  |  |  |   atom_t syntax_errors = ATOM_dec10; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     OPCODE ophook = PredCommentHook->OpcodeOfPred; | 
					
						
							|  |  |  |     if (ophook == UNDEF_OPCODE || ophook == FAIL_OPCODE) | 
					
						
							|  |  |  |       process_comment = FALSE; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       process_comment = TRUE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (!(fid = PL_open_foreign_frame())) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | retry: | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   init_read_data(&rd, s PASS_LD); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (options && | 
					
						
							|  |  |  |       !scan_options(options, 0, ATOM_read_option, read_clause_options, | 
					
						
							|  |  |  |                     &rd.varnames, &tpos, &rd.subtpos, &process_comment, | 
					
						
							|  |  |  |                     &opt_comments, &syntax_errors)) { | 
					
						
							|  |  |  |     PL_close_foreign_frame(fid); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (opt_comments) { | 
					
						
							|  |  |  |     comments = PL_new_term_ref(); | 
					
						
							|  |  |  |   } else if (process_comment) { | 
					
						
							|  |  |  |     if (!tpos) | 
					
						
							|  |  |  |       tpos = PL_new_term_ref(); | 
					
						
							|  |  |  |     comments = PL_new_term_ref(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   REGS_FROM_LD | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   rd.module = Yap_GetModuleEntry(LOCAL_SourceModule); | 
					
						
							|  |  |  |   if (comments) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     rd.comments = PL_copy_term_ref(comments); | 
					
						
							|  |  |  |   rd.on_error = syntax_errors; | 
					
						
							|  |  |  |   rd.singles = rd.styleCheck & SINGLETON_CHECK ? 1 : 0; | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if ((rval = read_term(term, &rd PASS_LD)) && | 
					
						
							|  |  |  |       (!tpos || (rval = unify_read_term_position(tpos PASS_LD)))) { | 
					
						
							|  |  |  |     PredEntry *ap; | 
					
						
							|  |  |  |     LD->read_varnames = rd.varnames; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (rd.singles) { | 
					
						
							|  |  |  |       // warning, singletons([X=_A],f(X,Y,Z), pos).
 | 
					
						
							|  |  |  |       printMessage(ATOM_warning, PL_FUNCTOR_CHARS, "singletons", 3, PL_TERM, | 
					
						
							|  |  |  |                    rd.singles, PL_TERM, term, PL_TERM, tpos); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ap = Yap_PredFromClause(Yap_GetFromSlot(term) PASS_REGS); | 
					
						
							|  |  |  |     if (rd.styleCheck & (DISCONTIGUOUS_STYLE | MULTIPLE_CHECK) && ap != NULL) { | 
					
						
							|  |  |  |       if (rd.styleCheck & (DISCONTIGUOUS_STYLE) && | 
					
						
							|  |  |  |           Yap_discontiguous(ap PASS_REGS)) { | 
					
						
							|  |  |  |         printMessage(ATOM_warning, PL_FUNCTOR_CHARS, "discontiguous", 2, | 
					
						
							|  |  |  |                      PL_TERM, term, PL_TERM, tpos); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |       if (rd.styleCheck & (MULTIPLE_CHECK) && Yap_multiple(ap PASS_REGS)) { | 
					
						
							|  |  |  |         printMessage(ATOM_warning, PL_FUNCTOR_CHARS, "multiple", 3, PL_TERM, | 
					
						
							|  |  |  |                      term, PL_TERM, tpos, PL_ATOM, | 
					
						
							|  |  |  |                      YAP_SWIAtomFromAtom(ap->src.OwnerFile)); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     if (rd.comments && (rval = PL_unify_nil(rd.comments))) { | 
					
						
							|  |  |  |       if (opt_comments) | 
					
						
							|  |  |  |         rval = PL_unify(opt_comments, comments); | 
					
						
							|  |  |  |       else if (!PL_get_nil(comments)) | 
					
						
							|  |  |  |         callCommentHook(comments, tpos, term); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     if (rd.has_exception && reportReadError(&rd)) { | 
					
						
							|  |  |  |       PL_rewind_foreign_frame(fid); | 
					
						
							|  |  |  |       free_read_data(&rd); | 
					
						
							|  |  |  |       goto retry; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   free_read_data(&rd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return rval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static PRED_IMPL("read_clause", 3, read_clause, 0) { | 
					
						
							|  |  |  |   PRED_LD | 
					
						
							|  |  |  |   int rc; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   IOSTREAM *s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (!getTextInputStream(A1, &s)) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   rc = read_clause(s, A2, A3 PASS_LD); | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (Sferror(s)) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     return streamStatus(s); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     PL_release_stream(s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return rc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | word pl_raw_read(term_t term) { return pl_raw_read2(0, term); } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static const opt_spec read_term_options[] = { | 
					
						
							|  |  |  |     {ATOM_variable_names, OPT_TERM}, | 
					
						
							|  |  |  |     {ATOM_variables, OPT_TERM}, | 
					
						
							|  |  |  |     {ATOM_singletons, OPT_TERM}, | 
					
						
							|  |  |  |     {ATOM_term_position, OPT_TERM}, | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     //  		{ ATOM_subterm_positions, OPT_TERM },
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     {ATOM_character_escapes, OPT_BOOL}, | 
					
						
							|  |  |  |     {ATOM_double_quotes, OPT_ATOM}, | 
					
						
							|  |  |  |     {ATOM_module, OPT_ATOM}, | 
					
						
							|  |  |  |     {ATOM_syntax_errors, OPT_ATOM}, | 
					
						
							|  |  |  |     {ATOM_backquoted_string, OPT_BOOL}, | 
					
						
							|  |  |  |     {ATOM_comments, OPT_TERM}, | 
					
						
							|  |  |  |     {ATOM_process_comment, OPT_BOOL}, | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #ifdef O_QUASIQUOTATIONS
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     {ATOM_quasi_quotations, OPT_TERM}, | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     {ATOM_cycles, OPT_BOOL}, | 
					
						
							|  |  |  |     {NULL_ATOM, 0}}; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static foreign_t read_term_from_stream(IOSTREAM *s, term_t term, | 
					
						
							|  |  |  |                                        term_t options ARG_LD) { | 
					
						
							|  |  |  |   term_t tpos = 0; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   term_t comments = 0; | 
					
						
							|  |  |  |   term_t opt_comments = 0; | 
					
						
							|  |  |  |   int process_comment; | 
					
						
							|  |  |  |   int rval; | 
					
						
							|  |  |  |   atom_t w; | 
					
						
							|  |  |  |   read_data rd; | 
					
						
							|  |  |  |   int charescapes = -1; | 
					
						
							|  |  |  |   atom_t dq = NULL_ATOM; | 
					
						
							|  |  |  |   atom_t mname = NULL_ATOM; | 
					
						
							|  |  |  |   fid_t fid = PL_open_foreign_frame(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!fid) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | retry: | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   init_read_data(&rd, s PASS_LD); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (!scan_options(options, 0, ATOM_read_option, read_term_options, | 
					
						
							|  |  |  |                     &rd.varnames, &rd.variables, &rd.singles, &tpos, | 
					
						
							|  |  |  |                     //		&rd.subtpos,
 | 
					
						
							|  |  |  |                     &charescapes, &dq, &mname, &rd.on_error, | 
					
						
							|  |  |  |                     &rd.backquoted_string, &opt_comments, &process_comment, | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #ifdef O_QUASIQUOTATIONS
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |                     &rd.quasi_quotations, | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |                     &rd.cycles)) { | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     PL_discard_foreign_frame(fid); | 
					
						
							|  |  |  |     free_read_data(&rd); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // yap specific, do not call process comment if undefined
 | 
					
						
							|  |  |  |   if (process_comment) { | 
					
						
							|  |  |  |     OPCODE ophook = PredCommentHook->OpcodeOfPred; | 
					
						
							|  |  |  |     if (ophook == UNDEF_OPCODE || ophook == FAIL_OPCODE) | 
					
						
							|  |  |  |       process_comment = FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (opt_comments) { | 
					
						
							|  |  |  |     comments = PL_new_term_ref(); | 
					
						
							|  |  |  |   } else if (process_comment) { | 
					
						
							|  |  |  |     if (!tpos) | 
					
						
							|  |  |  |       tpos = PL_new_term_ref(); | 
					
						
							|  |  |  |     comments = PL_new_term_ref(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (mname) { | 
					
						
							|  |  |  |     rd.module = lookupModule(mname); | 
					
						
							|  |  |  |     rd.flags = rd.module->flags; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (charescapes != -1) { | 
					
						
							|  |  |  |     if (charescapes) | 
					
						
							|  |  |  |       set(&rd, M_CHARESCAPE); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       clear(&rd, M_CHARESCAPE); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (dq) { | 
					
						
							|  |  |  |     if (!setDoubleQuotes(dq, &rd.flags)) | 
					
						
							|  |  |  |       return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (rd.singles && PL_get_atom(rd.singles, &w) && w == ATOM_warning) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     rd.singles = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (comments) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     rd.comments = PL_copy_term_ref(comments); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   rval = read_term(term, &rd PASS_LD); | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (Sferror(s)) { | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     free_read_data(&rd); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   LD->read_varnames = rd.varnames; | 
					
						
							|  |  |  | #ifdef O_QUASIQUOTATIONS
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (rval) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     rval = parse_quasi_quotations(&rd PASS_LD); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (rval) { | 
					
						
							|  |  |  |     if (tpos) | 
					
						
							|  |  |  |       rval = unify_read_term_position(tpos PASS_LD); | 
					
						
							|  |  |  |     if (rval) { | 
					
						
							|  |  |  |       if (opt_comments) | 
					
						
							|  |  |  |         rval = PL_unify(opt_comments, comments); | 
					
						
							|  |  |  |       else if (comments && !PL_get_nil(comments)) | 
					
						
							|  |  |  |         callCommentHook(comments, tpos, term); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } else { | 
					
						
							|  |  |  |     if (rd.has_exception && reportReadError(&rd)) { | 
					
						
							|  |  |  |       PL_rewind_foreign_frame(fid); | 
					
						
							|  |  |  |       free_read_data(&rd); | 
					
						
							|  |  |  |       goto retry; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   free_read_data(&rd); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return rval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** @pred  read_term(+ _Stream_,- _T_,+ _Options_) is iso
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Reads term  _T_ from stream  _Stream_ with execution controlled by the | 
					
						
							|  |  |  |     same options as read_term/2. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static PRED_IMPL("read_term", 3, read_term, PL_FA_ISO) { | 
					
						
							|  |  |  |   PRED_LD | 
					
						
							|  |  |  |   IOSTREAM *s; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (getTextInputStream(A1, &s)) { | 
					
						
							|  |  |  |     if (read_term_from_stream(s, A2, A3 PASS_LD)) | 
					
						
							|  |  |  |       return PL_release_stream(s); | 
					
						
							|  |  |  |     if (Sferror(s)) | 
					
						
							|  |  |  |       return streamStatus(s); | 
					
						
							|  |  |  |     PL_release_stream(s); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** read_term(-Term, +Options) is det.
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** @pred read_term(- _T_,+ _Options_) is iso
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Reads term  _T_ from the current input stream with execution | 
					
						
							|  |  |  |     controlled by the following options: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     + comments(- _Comments_) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Unify _Comments_ with a list of string terms including comments before | 
					
						
							|  |  |  |     and within the term. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     + module( + _Module_) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Read term using _Module_ as source module. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     + quasi_quotations(-List) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Unify _List_ with the quasi-quotations present in the term. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     + term_position(- _Position_) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Unify  _Position_ with a term describing the position of the stream | 
					
						
							|  |  |  |     at the start of parse. Use stream_position_data/3 to obtain extra | 
					
						
							|  |  |  |     information. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     + singletons(- _Names_) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Unify  _Names_ with a list of the form  _Name=Var_, where | 
					
						
							|  |  |  |     _Name_ is the name of a non-anonymous singleton variable in the | 
					
						
							|  |  |  |     original term, and `Var` is the variable's representation in | 
					
						
							|  |  |  |     YAP. | 
					
						
							|  |  |  |     The variables occur in left-to-right traversal order. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     + syntax_errors(+ _Val_) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Control action to be taken after syntax errors. See yap_flag/2 | 
					
						
							|  |  |  |     for detailed information. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     + variables(- _Names_) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Unify  _Names_ with a list of the form  _Name=Var_, where  _Name_ is | 
					
						
							|  |  |  |     the name of a non-anonymous variable in the original term, and  _Var_ | 
					
						
							|  |  |  |     is the variable's representation in YAP. | 
					
						
							|  |  |  |     The variables occur in left-to-right traversal order. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static PRED_IMPL("read_term", 2, read_term, PL_FA_ISO) { | 
					
						
							|  |  |  |   PRED_LD | 
					
						
							|  |  |  |   IOSTREAM *s; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (getTextInputStream(0, &s)) { | 
					
						
							|  |  |  |     if (read_term_from_stream(s, A1, A2 PASS_LD)) | 
					
						
							|  |  |  |       return PL_release_stream(s); | 
					
						
							|  |  |  |     if (Sferror(s)) | 
					
						
							|  |  |  |       return streamStatus(s); | 
					
						
							|  |  |  |     PL_release_stream(s); | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return FALSE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************
 | 
					
						
							|  |  |  |  *	   TERM <->ATOM		* | 
					
						
							|  |  |  |  *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static int atom_to_term(term_t atom, term_t term, term_t bindings) { | 
					
						
							|  |  |  |   GET_LD | 
					
						
							|  |  |  |   PL_chars_t txt; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!bindings && PL_is_variable(atom)) /* term_to_atom(+, -) */ | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     char buf[1024]; | 
					
						
							|  |  |  |     size_t bufsize = sizeof(buf); | 
					
						
							|  |  |  |     int rval; | 
					
						
							|  |  |  |     char *s = buf; | 
					
						
							|  |  |  |     IOSTREAM *stream; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     PL_chars_t txt; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     stream = Sopenmem(&s, &bufsize, "w"); | 
					
						
							|  |  |  |     stream->encoding = ENC_UTF8; | 
					
						
							|  |  |  |     PL_write_term(stream, term, 1200, PL_WRT_QUOTED); | 
					
						
							|  |  |  |     Sflush(stream); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     txt.text.t = s; | 
					
						
							|  |  |  |     txt.length = bufsize; | 
					
						
							|  |  |  |     txt.storage = PL_CHARS_HEAP; | 
					
						
							|  |  |  |     txt.encoding = ENC_UTF8; | 
					
						
							|  |  |  |     txt.canonical = FALSE; | 
					
						
							|  |  |  |     rval = PL_unify_text(atom, 0, &txt, PL_ATOM); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     Sclose(stream); | 
					
						
							|  |  |  |     if (s != buf) | 
					
						
							|  |  |  |       Sfree(s); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     return rval; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (PL_get_text(atom, &txt, CVT_ALL | CVT_EXCEPTION)) { | 
					
						
							|  |  |  |     GET_LD | 
					
						
							|  |  |  |     read_data rd; | 
					
						
							|  |  |  |     int rval; | 
					
						
							|  |  |  |     IOSTREAM *stream; | 
					
						
							|  |  |  |     source_location oldsrc = LD->read_source; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     stream = Sopen_text(&txt, "r"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     init_read_data(&rd, stream PASS_LD); | 
					
						
							|  |  |  |     if (bindings && (PL_is_variable(bindings) || PL_is_list(bindings))) | 
					
						
							|  |  |  |       rd.varnames = bindings; | 
					
						
							|  |  |  |     else if (bindings) | 
					
						
							|  |  |  |       return PL_error(NULL, 0, NULL, ERR_TYPE, ATOM_list, bindings); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!(rval = read_term(term, &rd PASS_LD)) && rd.has_exception) | 
					
						
							|  |  |  |       rval = PL_raise_exception(rd.exception); | 
					
						
							|  |  |  |     free_read_data(&rd); | 
					
						
							|  |  |  |     Sclose(stream); | 
					
						
							|  |  |  |     LD->read_source = oldsrc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     //   getchar();
 | 
					
						
							|  |  |  |     return rval; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   fail; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | Term Yap_CharsToTerm(const char *s, size_t *lenp, Term *bindingsp) { | 
					
						
							|  |  |  |   GET_LD; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   read_data rd; | 
					
						
							|  |  |  |   int rval; | 
					
						
							|  |  |  |   IOSTREAM *stream; | 
					
						
							|  |  |  |   source_location oldsrc = LD->read_source; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   stream = Sopen_string(0, (char *)s, strlen(s), "r"); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   init_read_data(&rd, stream PASS_LD); | 
					
						
							|  |  |  |   rd.varnames = bindings; | 
					
						
							|  |  |  |   term_t tt = Yap_NewSlots(1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (!(rval = read_term(tt, &rd PASS_LD)) && rd.has_exception) { | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     rval = PL_raise_exception(rd.exception); | 
					
						
							|  |  |  |     return 0L; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   free_read_data(&rd); | 
					
						
							|  |  |  |   Sclose(stream); | 
					
						
							|  |  |  |   LD->read_source = oldsrc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //   getchar();
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   return Yap_GetFromSlot(tt); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** @pred atom_to_term(+ _Atom_, - _Term_, - _Bindings_)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     Use  _Atom_ as input to read_term/2 using the option `variable_names` and | 
					
						
							|  |  |  |    return the read term in  _Term_ and the variable bindings in  _Bindings_. | 
					
						
							|  |  |  |    _Bindings_ is a list of `Name = Var` couples, thus providing access to the | 
					
						
							|  |  |  |    actual variable names. See also read_term/2. If Atom has no valid syntax, a | 
					
						
							|  |  |  |    syntax_error exception is raised. | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static PRED_IMPL("atom_to_term", 3, atom_to_term, 0) { | 
					
						
							|  |  |  |   return atom_to_term(A1, A2, A3); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static PRED_IMPL("term_to_atom", 2, term_to_atom, 0) { | 
					
						
							|  |  |  |   return atom_to_term(A2, A1, 0); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static PRED_IMPL("$context_variables", 1, context_variables, 0) { | 
					
						
							|  |  |  |   CACHE_REGS | 
					
						
							|  |  |  |   if (LOCAL_VarNames == (CELL)0) | 
					
						
							|  |  |  |     return Yap_unify(TermNil, ARG1); | 
					
						
							|  |  |  |   return Yap_unify(LOCAL_VarNames, ARG1); | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | static PRED_IMPL("$set_source", 2, set_source, 0) { | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   GET_LD | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   atom_t at; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   term_t a = PL_new_term_ref(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!PL_get_atom(A1, &at)) | 
					
						
							|  |  |  |     return FALSE; | 
					
						
							|  |  |  |   source_file_name = at; | 
					
						
							|  |  |  |   if (!PL_get_arg(1, A2, a) || !PL_get_int64(a, &source_char_no) || | 
					
						
							|  |  |  |       !PL_get_arg(2, A2, a) || !PL_get_long(a, &source_line_no) || | 
					
						
							|  |  |  |       !PL_get_arg(3, A2, a) || !PL_get_long(a, &source_line_pos) || | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |       !PL_get_arg(4, A2, a) || !PL_get_int64(a, &source_byte_no)) { | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     return FALSE; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return TRUE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | int PL_chars_to_term(const char *s, term_t t) { | 
					
						
							|  |  |  |   GET_LD | 
					
						
							|  |  |  |   read_data rd; | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |   int rval; | 
					
						
							|  |  |  |   IOSTREAM *stream = Sopen_string(NULL, (char *)s, -1, "r"); | 
					
						
							|  |  |  |   source_location oldsrc = LD->read_source; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   init_read_data(&rd, stream PASS_LD); | 
					
						
							|  |  |  |   PL_put_variable(t); | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |   if (!(rval = read_term(t, &rd PASS_LD)) && rd.has_exception) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  |     PL_put_term(t, rd.exception); | 
					
						
							|  |  |  |   LOCAL_VarNames = rd.varnames; | 
					
						
							|  |  |  |   free_read_data(&rd); | 
					
						
							|  |  |  |   Sclose(stream); | 
					
						
							|  |  |  |   LD->read_source = oldsrc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return rval; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*******************************
 | 
					
						
							|  |  |  |  *      PUBLISH PREDICATES	* | 
					
						
							|  |  |  |  *******************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  | BeginPredDefs(read) PRED_DEF("read_term", 3, read_term, PL_FA_ISO) | 
					
						
							|  |  |  |     PRED_DEF("read_term", 2, read_term, PL_FA_ISO) | 
					
						
							|  |  |  |         PRED_DEF("read_clause", 3, read_clause, 0) | 
					
						
							|  |  |  |             PRED_DEF("atom_to_term", 3, atom_to_term, 0) | 
					
						
							|  |  |  |                 PRED_DEF("term_to_atom", 2, term_to_atom, 0) | 
					
						
							|  |  |  |                     PRED_DEF("$context_variables", 1, context_variables, 0) | 
					
						
							|  |  |  |                         PRED_DEF("$set_source", 2, set_source, 0) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #ifdef O_QUASIQUOTATIONS
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |                             PRED_DEF("$qq_open", 2, qq_open, 0) | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |                                 EndPredDefs | 
					
						
							| 
									
										
										
										
											2015-06-18 01:47:23 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-04 12:52:42 -06:00
										 |  |  |     //! @}
 |