YAP 7.1.0
flags.c
Go to the documentation of this file.
1/*************************************************************************
2 * *
3 * YAP Prolog *
4 * *
5 * Yap Prolog was developed at NCCUP - Universidade do Porto *
6 * *
7 * Copyright L.Damas, V.S.Costa and Universidade do Porto 2015- *
8 * *
9 **************************************************************************
10 * *
11 * File: flags.c *
12 * Last rev: *
13 * mods: *
14 * comments: abstract machine definitions *
15 * *
16 *************************************************************************/
17
34// this is where we define flags
35
36
37#include "Yap.h"
38
39#define INIT_FLAGS 1
40#include "iopreds.h"
41#if HAVE_UNISTD_H
42#include <unistd.h>
43#endif
44
45 Term ro(Term inp);
46 Term nat(Term inp);
47 Term isatom(Term inp);
48 Term booleanFlag(Term inp);
49// static bool string( Term inp );
50// static bool list_atom( Term inp );
51static Term list_option(Term inp);
52static Term argv(Term inp);
53static Term os_argv(Term inp);
54static bool agc_threshold(Term inp);
55static bool gc_margin(Term inp);
56static Term executable(Term inp);
57static Term sys_thread_id(Term inp);
58static Term sys_pid(Term inp);
59static bool mkprompt(Term inp);
60static Term indexer(Term inp);
61static Term stream(Term inp);
62static bool getenc(Term inp);
63static bool typein(Term inp);
64static bool dqs(Term t2);
65static bool bqs(Term t2);
66static bool sqf(Term t2);
67static bool set_error_stream(Term inp);
68static bool set_input_stream(Term inp);
69static bool set_output_stream(Term inp);
70static bool dollar_to_lc(Term inp);
71static bool setSignals(Term inp);
72
73static void newFlag(Term fl, Term val);
74static Int current_prolog_flag(USES_REGS1);
75static Int set_prolog_flag(USES_REGS1);
76
77#include "YapEval.h"
78#include "Yatom.h"
79#include "yapio.h"
80
81
82static Term compiling(Term inp) {
83 if (LOCAL_consult_level) return Yap_unify(inp,TermTrue);
84 return Yap_unify(inp,TermFalse);
85}
86
87Term ro(Term inp) {
88 if (IsVarTerm(inp)) {
89 Yap_ThrowError(INSTANTIATION_ERROR, inp, "set_prolog_flag: value must be %s",
90 "bound");
91 return TermZERO;
92 }
93 Yap_ThrowError(PERMISSION_ERROR_READ_ONLY_FLAG, inp, "set_prolog_flag %s",
94 "flag is read-only");
95 return TermZERO;
96}
97
98Term aro(Term inp) {
99 if (IsVarTerm(inp)) {
100 Yap_ThrowError(INSTANTIATION_ERROR, inp, "set_prolog_flag %s",
101 "value must be bound");
102}
103 return TermZERO;
104 }
105
106
107Term booleanFlag(Term inp) {
108 if (IsStringTerm(inp)) {
109 inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE);
110 }
111 if (inp == TermTrue || inp == TermOn)
112 return TermTrue;
113 if (inp == TermFalse || inp == TermOff)
114 return TermFalse;
115 if (IsVarTerm(inp)) {
116 Yap_ThrowError(INSTANTIATION_ERROR, inp, "set_prolog_flag %s",
117 "value must be bound");
118 ;
119 return TermZERO;
120 }
121 if (IsAtomTerm(inp)) {
122 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, inp,
123 "set_prolog_flag in {true,false,on,off}");
124 return TermZERO;
125 }
126 Yap_ThrowError(TYPE_ERROR_ATOM, inp, "set_prolog_flag in {true,false,on,off");
127 return TermZERO;
128}
129
130
131 Term febooleanFlag(Term inp) {
132 if (IsStringTerm(inp)) {
133 inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE);
134 }
135 if (inp == TermTrue || inp == TermError)
136 return TermError;
137 if (inp == TermFalse || inp == TermFail)
138 return TermFail;
139 if (IsVarTerm(inp)) {
140 Yap_ThrowError(INSTANTIATION_ERROR, inp, "set_prolog_flag %s",
141 "value must be bound");
142 ;
143 return TermZERO;
144 }
145 if (IsAtomTerm(inp)) {
146 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, inp,
147 "set_prolog_flag in {true,false,on,off}");
148 return TermZERO;
149 }
150 Yap_ThrowError(TYPE_ERROR_ATOM, inp, "set_prolog_flag in {true,false,error,fail");
151 return TermZERO;
152}
153
154Term synerr(Term inp){
155 if (IsStringTerm(inp)) {
156 inp = MkAtomTerm(Yap_LookupAtom(StringOfTerm(inp)));
157 }
158 if (inp == TermDec10 || inp == TermFail || inp == TermError ||
159 inp == TermQuiet)
160 return inp;
161
162 if (IsAtomTerm(inp)) {
163 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, inp,
164 "set_prolog_flag in {dec10,error,fail,quiet}");
165 return TermZERO;
166 }
167 Yap_ThrowError(TYPE_ERROR_ATOM, inp,
168 "syntax_error flag must be atom");
169 return TermZERO;
170}
171
172#define YAP_FLAG(ID, NAME, WRITABLE, DEF, INIT, HELPER) \
173 { NAME, WRITABLE, DEF, INIT, HELPER }
174
175#define START_LOCAL_FLAGS static flag_info local_flags_setup[] = {
176#define END_LOCAL_FLAGS \
177 LZERO_FLAG \
178 } \
179 ;
180
181#define START_GLOBAL_FLAGS static flag_info global_flags_setup[] = {
182#define END_GLOBAL_FLAGS \
183 GZERO_FLAG \
184 } \
185 ;
186
187#define GZERO_FLAG \
188 { NULL, false, NULL, NULL, NULL }
189#define LZERO_FLAG \
190 { NULL, false, NULL, NULL, NULL }
191
192#include "YapGFlagInfo.h"
193
194#include "YapLFlagInfo.h"
195
196static Term indexer(Term inp) {
197 if (IsStringTerm(inp)) {
198 inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE);
199 }
200 if (inp == TermOff || inp == TermSingle || inp == TermCompact ||
201 inp == TermMulti || inp == TermOn || inp == TermMax)
202 return inp;
203
204 if (IsAtomTerm(inp)) {
205 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, inp,
206 "set_prolog_flag index in {off,single,compact,multi,on,max}");
207 return TermZERO;
208 }
209 Yap_ThrowError(TYPE_ERROR_ATOM, inp, "set_prolog_flag index to an atom");
210 return TermZERO;
211}
212
220static bool setSignals(Term inp) {
221 bool handle = (inp == TermTrue || inp == TermOn);
222 if (handle != GLOBAL_PrologShouldHandleInterrupts) {
223 Yap_InitSignals(0);
224 }
225 GLOBAL_PrologShouldHandleInterrupts = handle;
226 return true;
227 }
228
229static bool dqf1(ModEntry *new, Term t2 USES_REGS) {
230 new->flags &= ~(DBLQ_CHARS | DBLQ_CODES | DBLQ_ATOM | DBLQ_STRING);
231 if (IsStringTerm(t2)) {
232 t2 = MkStringTerm(RepAtom(AtomOfTerm(t2))->StrOfAE);
233 }
234 if (IsAtomTerm(t2)) {
235 if (t2 == TermString) {
236 new->flags |= DBLQ_STRING;
237 return true;
238 } else if (t2 == TermAtom) {
239 new->flags |= DBLQ_ATOM;
240 return true;
241 } else if (t2 == TermCodes) {
242 new->flags |= DBLQ_CODES;
243 return true;
244 } else if (t2 == TermChars) {
245 new->flags |= DBLQ_CHARS;
246 return true;
247 }
248 /* bad argument, but still an atom */
249 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2,
250 "bad option %s for backquoted "
251 "string flag, use one string, "
252 "atom, codes or chars",
253 RepAtom(AtomOfTerm(t2))->StrOfAE);
254 return false;
255 } else {
256 Yap_ThrowError(TYPE_ERROR_ATOM, t2,
257 "set_prolog_flag(double_quotes, %s), should "
258 "be {string,atom,codes,chars}",
259 RepAtom(AtomOfTerm(t2))->StrOfAE);
260 return false;
261 }
262}
263
264static bool dqs(Term t2) {
265 CACHE_REGS
266 ModEntry *new = Yap_GetModuleEntry(CurrentModule);
267 return dqf1(new, t2 PASS_REGS);
268}
269
270static bool bqf1(ModEntry *new, Term t2 USES_REGS) {
271 new->flags &= ~(BCKQ_CHARS | BCKQ_CODES | BCKQ_ATOM | BCKQ_STRING);
272 if (IsStringTerm(t2)) {
273 t2 = MkStringTerm(RepAtom(AtomOfTerm(t2))->StrOfAE);
274 }
275 if (IsAtomTerm(t2)) {
276 if (t2 == TermString) {
277 new->flags |= BCKQ_STRING;
278 return true;
279 } else if (t2 == TermAtom) {
280 new->flags |= BCKQ_ATOM;
281 return true;
282 } else if (t2 == TermCodes) {
283 new->flags |= BCKQ_CODES;
284 return true;
285 } else if (t2 == TermChars) {
286 new->flags |= BCKQ_CHARS;
287 return true;
288 }
289 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2,
290 "bad option %s for backquoted "
291 "string flag, use one string, "
292 "atom, codes or chars",
293 RepAtom(AtomOfTerm(t2))->StrOfAE);
294 return false;
295 } else {
296 Yap_ThrowError(TYPE_ERROR_ATOM, t2, "flag %s is not module-scoped",
297 RepAtom(AtomOfTerm(t2))->StrOfAE);
298 return false;
299 }
300}
301
302static bool bqs(Term t2) {
303 CACHE_REGS
304 ModEntry *new = Yap_GetModuleEntry(CurrentModule);
305 return bqf1(new, t2 PASS_REGS);
306}
307
308static bool sqf1(ModEntry *new, Term t2 USES_REGS) {
309 new->flags &= ~(SNGQ_CHARS | SNGQ_CODES | SNGQ_ATOM | SNGQ_STRING);
310 if (IsStringTerm(t2)) {
311 t2 = MkStringTerm(RepAtom(AtomOfTerm(t2))->StrOfAE);
312 }
313 if (IsAtomTerm(t2)) {
314 if (t2 == TermString) {
315 new->flags |= SNGQ_STRING;
316 return true;
317 } else if (t2 == TermAtom) {
318 new->flags |= SNGQ_ATOM;
319 return true;
320 } else if (t2 == TermCodes) {
321 new->flags |= SNGQ_CODES;
322 return true;
323 } else if (t2 == TermChars) {
324 new->flags |= SNGQ_CHARS;
325 return true;
326 }
327 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2,
328 "bad option %s for backquoted "
329 "string flag, use one string, "
330 "atom, codes or chars",
331 RepAtom(AtomOfTerm(t2))->StrOfAE);
332 return false;
333 } else {
334 Yap_ThrowError(TYPE_ERROR_ATOM, t2, "flag %s is not module-scoped",
335 RepAtom(AtomOfTerm(t2))->StrOfAE);
336 return false;
337 }
338}
339
340static bool sqf(Term t2) {
341 CACHE_REGS
342 ModEntry *new = Yap_GetModuleEntry(CurrentModule);
343 return sqf1(new, t2 PASS_REGS);
344}
345
346static bool dollar_to_lc(Term inp) {
347 if (inp == TermTrue || inp == TermOn) {
348 Yap_chtype0['$'+1] = LC;
349 return true;
350 }
351 if (inp == TermFalse || inp == TermOff) {
352 Yap_chtype0['$'+1] = CC;
353 return false;
354 }
355 Yap_ThrowError(TYPE_ERROR_BOOLEAN, inp,
356 "dollar_to_lower_case is a boolean flag");
357 return TermZERO;
358 }
359
360static Term isaccess(Term inp) {
361 if (inp == TermReadWrite || inp == TermReadOnly)
362 return inp;
363
364 if (IsStringTerm(inp)) {
365 inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE);
366 }
367 if (IsAtomTerm(inp)) {
368 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, inp,
369 "set_prolog_flag access in {read_write,read_only}");
370 return TermZERO;
371 }
372 Yap_ThrowError(TYPE_ERROR_ATOM, inp,
373 "set_prolog_flag access to the {read_write,read_only}");
374 return TermZERO;
375}
376
377
378static Term stream(Term inp) {
379 if (IsVarTerm(inp))
380 return true;
381 if (Yap_CheckStream(inp,
382 Input_Stream_f | Output_Stream_f | Append_Stream_f |
383 Socket_Stream_f,
384 "yap_flag/3") >= 0)
385 return inp;
386 return 0;
387}
388
389static bool set_input_stream(Term inp) {
390
391 if (IsVarTerm(inp))
392 return Yap_unify(inp,
393 Yap_MkStream(LOCAL_c_input_stream));
394
395 int sno = Yap_CheckStream(inp,
396 Input_Stream_f |
397 Socket_Stream_f,
398 "yap_flag/3") ;
399 return Yap_AddAlias(AtomUserIn,sno);
400}
401
402static bool set_output_stream(Term inp) {
403 int sno;
404 if (IsVarTerm(inp))
405 return Yap_unify(inp,
406 Yap_MkStream(LOCAL_c_output_stream));
407
408 sno = Yap_CheckStream(inp,
409 Output_Stream_f | Append_Stream_f |
410 Socket_Stream_f,
411 "yap_flag/3") ;
412 return Yap_AddAlias(AtomUserOut,sno);
413}
414
415static bool set_error_stream(Term inp) {
416 int sno;
417 if (IsVarTerm(inp))
418 return Yap_unify(inp,
419 Yap_MkStream(LOCAL_c_error_stream));
420 sno =
421 Yap_CheckStream(inp,
422 Output_Stream_f | Append_Stream_f |
423 Socket_Stream_f,
424 "yap_flag/3") ;
425 return Yap_AddAlias(AtomUserErr,sno);
426}
427
428
429static Term isground(Term inp) {
430 return Yap_IsGroundTerm(inp) ? inp : TermZERO;
431}
432
433static Term flagscope(Term inp) {
434 if (inp == TermGlobal || inp == TermThread || inp == TermModule)
435 return inp;
436
437 if (IsStringTerm(inp)) {
438 inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE);
439 }
440 if (IsAtomTerm(inp)) {
441 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, inp,
442 "set_prolog_flag access in {global,module,thread}");
443 return TermZERO;
444 }
445 Yap_ThrowError(TYPE_ERROR_ATOM, inp,
446 "set_prolog_flag access in {global,module,thread}");
447 return TermZERO;
448}
449
450static bool mkprompt(Term inp) {
451 CACHE_REGS
452 if (IsVarTerm(inp)) {
453 return Yap_unify(inp, MkAtomTerm(Yap_LookupAtom(LOCAL_Prompt)));
454 }
455 if (IsStringTerm(inp)) {
456 inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE);
457 }
458 if (!IsAtomTerm(inp)) {
459 Yap_ThrowError(TYPE_ERROR_ATOM, inp, "set_prolog_flag");
460 return false;
461 }
462 strncpy(LOCAL_Prompt, (const char *)RepAtom(AtomOfTerm(inp))->StrOfAE,
463 MAX_PROMPT);
464 return true;
465}
466
467static bool getenc(Term inp) {
468 CACHE_REGS
469 if (IsStringTerm(inp)) {
470 inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE);
471 }
472 if (!IsVarTerm(inp) && !IsAtomTerm(inp)) {
473 Yap_ThrowError(TYPE_ERROR_ATOM, inp, "get_encoding");
474 return false;
475 }
476 return Yap_unify(inp, MkAtomTerm(Yap_LookupAtom(enc_name(LOCAL_encoding))));
477}
478
479/*
480static bool enablerl( Term inp ) {
481CACHE_REGS
482if (IsVarTerm(inp)) {
483return Yap_unify( inp, MkAtomTerm( Yap_LookupAtom( enc_name(LOCAL_encoding)
484)) );
485}
486if (!IsAtomTerm(inp) ) {
487Yap_ThrowError(TYPE_ERROR_ATOM, inp, "set_prolog_flag");
488return false;
489}
490enc_id( RepAtom( AtomOfTerm( inp ) )->StrOfAE, ENC_OCTET );
491return true;
492}
493*/
494
495static bool typein(Term inp) {
496 CACHE_REGS
497 if (IsVarTerm(inp)) {
498 Term tin = CurrentModule;
499 if (tin == PROLOG_MODULE)
500 tin = TermProlog;
501 return Yap_unify(inp, tin);
502 }
503 if (IsStringTerm(inp)) {
504 inp = MkAtomTerm(Yap_LookupAtom(StringOfTerm(inp)));
505 }
506 if (!IsAtomTerm(inp)) {
507 Yap_ThrowError(TYPE_ERROR_ATOM, inp, "set_prolog_flag");
508 return false;
509 }
510 CurrentModule = inp;
511 if (inp == TermProlog)
512 CurrentModule = PROLOG_MODULE;
513 return true;
514}
515
516#if 0
517
518 static Int p_has_yap_or(USES_REGS1) {
519#ifdef YAPOR
520 return (TRUE);
521#else
522 return (FALSE);
523#endif
524 }
525
526 static Int p_has_eam(USES_REGS1) {
527
528#ifdef BEAM
529 return (TRUE);
530#else
531 return (FALSE);
532#endif
533 }
534
535 static Int p_has_jit(USES_REGS1) {
536#ifdef HAS_JIT
537 return (TRUE);
538#else
539 return (FALSE);
540#endif
541 }
542
543 static bool tabling( Term inp ) {
544 if (value == 0) { /* default */
545 tab_ent_ptr tab_ent = GLOBAL_root_tab_ent;
546 while (tab_ent) {
547 TabEnt_mode(tab_ent) = TabEnt_flags(tab_ent);
548 tab_ent = TabEnt_next(tab_ent);
549 }
550 yap_flags[TA BLING_MODE_FLAG] = 0;
551 } else if (value == 1) { /* batched */
552 tab_ent_ptr tab_ent = GLOBAL_root_tab_ent;
553 while (tab_ent) {
554 SetMode_Batched(TabEnt_mode(tab_ent));
555 tab_ent = TabEnt_next(tab_ent);
556 }
557 SetMode_Batched(yap_flags[TABLING_MODE_FLAG]);
558 } else if (value == 2) { /* local */
559 tab_ent_ptr tab_ent = GLOBAL_root_tab_ent;
560 while (tab_ent) {
561 SetMode_Local(TabEnt_mode(tab_ent));
562 tab_ent = TabEnt_next(tab_ent);
563 }
564 SetMode_Local(yap_flags[TABLING_MODE_FLAG]);
565 } else if (value == 3) { /* exec_answers */
566 tab_ent_ptr tab_ent = GLOBAL_root_tab_ent;
567 while (tab_ent) {
568 SetMode_ExecAnswers(TabEnt_mode(tab_ent));
569 tab_ent = TabEnt_next(tab_ent);
570 }
571 SetMode_ExecAnswers(yap_flags[TABLING_MODE_FLAG]);
572 } else if (value == 4) { /* load_answers */
573 tab_ent_ptr tab_ent = GLOBAL_root_tab_ent;
574 while (tab_ent) {
575 SetMode_LoadAnswers(TabEnt_mode(tab_ent));
576 tab_ent = TabEnt_next(tab_ent);
577 }
578 SetMode_LoadAnswers(yap_flags[TABLING_MODE_FLAG]);
579 } else if (value == 5) { /* local_trie */
580 tab_ent_ptr tab_ent = GLOBAL_root_tab_ent;
581 while (tab_ent) {
582 SetMode_LocalTrie(TabEnt_mode(tab_ent));
583 tab_ent = TabEnt_next(tab_ent);
584 }
585 SetMode_LocalTrie(yap_flags[TABLING_MODE_FLAG]);
586 } else if (value == 6) { /* global_trie */
587 tab_ent_ptr tab_ent = GLOBAL_root_tab_ent;
588 while (tab_ent) {
589 SetMode_GlobalTrie(TabEnt_mode(tab_ent));
590 tab_ent = TabEnt_next(tab_ent);
591 }
592 SetMode_GlobalTrie(yap_flags[TABLING_MODE_FLAG]);
593 } else if (value == 7) { /* CoInductive */
594 tab_ent_ptr tab_ent = GLOBAL_root_tab_ent;
595 while (tab_ent) {
596 SetMode_CoInductive(TabEnt_mode(tab_ent));
597 tab_ent = TabEnt_next(tab_ent);
598 }
599 SetMode_CoInductive(yap_flags[TABLING_MODE_FLAG]);
600 }
601 }
602
603 static bool string( Term inp ) {
604 if (IsVarTerm(inp)) {
605 Yap_ThrowError(INSTANTIATION_ERROR, inp, "set_prolog_flag in \"...\"");
606 return false;
607 }
608 if (IsStringTerm( inp ))
609 return true;
610 Term inp0 = inp;
611 if (IsPairTerm(inp)) {
612 Term hd = HeadOfTerm(inp);
613 if (IsAtomTerm(hd)) {
614 do {
615 Term hd = HeadOfTerm(inp);
616 if (IsStringTerm(hd)) {
617 hd = MkStringTerm(RepAtom(AtomOfTerm(hd))->StrOfAE);
618 }
619 if (!IsAtomTerm(hd)) {
620 Yap_ThrowError(TYPE_ERROR_TEXT, inp0, "set_prolog_flag in \"...\"");
621 return false;
622 }
623 } while (IsPairTerm( inp ) );
624 } else if (IsIntTerm(hd)) {
625 do {
626 Term hd = HeadOfTerm(inp);
627 if (!IsIntTerm(hd)) {
628 Yap_ThrowError(TYPE_ERROR_TEXT, inp0, "set_prolog_flag in \"...\"");
629 return false;
630 }
631 if (IntOfTerm(hd) < 0) {
632 Yap_ThrowError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, inp0, "set_prolog_flag in 0...");
633 return false;
634 }
635 } while (IsPairTerm( inp ) );
636 } else {
637 Yap_ThrowError(TYPE_ERROR_TEXT, inp0, "set_prolog_flag in \"...\"");
638 return false;
639 }
640 }
641 if ( inp != TermNil ) {
642 Yap_ThrowError(TYPE_ERROR_TEXT, inp0, "set_prolog_flag in \"...\"");
643 return false;
644 }
645 return true;
646 }
647
648x static bool list_atom( Term inp ) {
649 if (IsVarTerm(inp)) {
650 Yap_ThrowError(INSTANTIATION_ERROR, inp, "set_prolog_flag in \"...\"");
651 return false;
652 }
653 Term inp0 = inp;
654 if (IsPairTerm(inp)) {
655 Term hd = HeadOfTerm(inp);
656 do {
657 if (IsStringTerm(hd)) {
658 hd = MkStringTerm(RepAtom(AtomOfTerm(hd))->StrOfAE);
659 }
660
661 if (!IsAtomTerm(hd)) {
662 Yap_ThrowError(TYPE_ERROR_ATOM, inp0, "set_prolog_flag in \"...\"");
663 return false;
664 }
665 } while (IsPairTerm( inp ) );
666 }
667 if ( inp != TermNil ) {
668 Yap_ThrowError(TYPE_ERROR_LIST, inp0, "set_prolog_flag in [...]");
669 return false;
670 }
671 return true;
672 }
673#endif
674
675static Term list_option(Term inp) {
676 if (IsVarTerm(inp)) {
677 Yap_ThrowError(INSTANTIATION_ERROR, inp, "set_prolog_flag in \"...\"");
678 return inp;
679 }
680 Term inp0 = inp;
681 if (IsPairTerm(inp)) {
682 do {
683 Term hd = HeadOfTerm(inp);
684 inp = TailOfTerm(inp);
685 if (IsStringTerm(hd)) {
686 hd = MkStringTerm(RepAtom(AtomOfTerm(hd))->StrOfAE);
687 }
688 if (IsAtomTerm(hd)) {
689 continue;
690 }
691 if (IsApplTerm(hd)) {
692 Functor f = FunctorOfTerm(hd);
693 if (!IsExtensionFunctor(f) && ArityOfFunctor(f) == 1 &&
694 Yap_IsGroundTerm(hd)) {
695 continue;
696 }
697 if (!Yap_IsGroundTerm(hd))
698 Yap_ThrowError(INSTANTIATION_ERROR, hd, "set_prolog_flag in \"...\"");
699 return TermZERO;
700 }
701 } while (IsPairTerm(inp));
702 if (inp == TermNil) {
703 return inp0;
704 }
705 Yap_ThrowError(TYPE_ERROR_LIST, inp0, "set_prolog_flag in [...]");
706 return TermZERO;
707 } else /* lone option */ {
708 if (IsStringTerm(inp)) {
709 inp = MkStringTerm(RepAtom(AtomOfTerm(inp))->StrOfAE);
710 }
711 if (IsAtomTerm(inp)) {
712 return inp;
713 } else if (IsApplTerm(inp)) {
714 Functor f = FunctorOfTerm(inp);
715 if (!IsExtensionFunctor(f) && ArityOfFunctor(f) == 1 &&
716 Yap_IsGroundTerm(ArgOfTerm(1, inp))) {
717 return inp;
718 }
719 }
720 }
721 return TermZERO;
722}
723
724static bool agc_threshold(Term t) {
725 t = Deref(t);
726 if (IsVarTerm(t)) {
727 CACHE_REGS
728 return Yap_unify(t, MkIntegerTerm(GLOBAL_AGcThreshold));
729 } else if (!IsIntegerTerm(t)) {
730 Yap_ThrowError(TYPE_ERROR_INTEGER, t, "prolog_flag/2 agc_margin");
731 return FALSE;
732 } else {
733 Int i = IntegerOfTerm(t);
734 if (i < 0) {
735 Yap_ThrowError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t, "prolog_flag/2 agc_margin");
736 return FALSE;
737 } else {
738 GLOBAL_AGcThreshold = i;
739 return TRUE;
740 }
741 }
742}
743
744static bool gc_margin(Term t) {
745 t = Deref(t);
746 if (IsVarTerm(t)) {
747 return Yap_unify(t, Yap_GetValue(AtomGcMargin));
748 } else if (!IsIntegerTerm(t)) {
749 Yap_ThrowError(TYPE_ERROR_INTEGER, t, "prolog_flag/2 agc_margin");
750 return FALSE;
751 } else {
752 Int i = IntegerOfTerm(t);
753 if (i < 0) {
754 Yap_ThrowError(DOMAIN_ERROR_NOT_LESS_THAN_ZERO, t, "prolog_flag/2 gc_margin");
755 return FALSE;
756 } else {
757 CACHE_REGS
758 Yap_PutValue(AtomGcMargin, MkIntegerTerm(i));
759 return true;
760 }
761 }
762}
763
764static Term mk_argc_list(USES_REGS1) {
765 int i = 1;
766 Term t = TermNil;
767 while (i < GLOBAL_argc) {
768 char *arg = GLOBAL_argv[i];
769 /* check for -L -- */
770 if (arg[0] == '-' && arg[1] == 'L') {
771 arg += 2;
772 while (*arg != '\0' && (*arg == ' ' || *arg == '\t'))
773 arg++;
774 if (*arg == '-' && arg[1] == '-' && arg[2] == '\0') {
775 /* we found the separator */
776 int j;
777 for (j = GLOBAL_argc - 1; j > i + 1; --j) {
778 t = MkPairTerm(MkAtomTerm(Yap_LookupAtom(GLOBAL_argv[j])), t);
779 }
780 return t;
781 } else if (GLOBAL_argv[i + 1] && GLOBAL_argv[i + 1][0] == '-' &&
782 GLOBAL_argv[i + 1][1] == '-' &&
783 GLOBAL_argv[i + 1][2] == '\0') {
784 /* we found the separator */
785 int j;
786 for (j = GLOBAL_argc - 1; j > i + 2; --j) {
787 t = MkPairTerm(MkAtomTerm(Yap_LookupAtom(GLOBAL_argv[j])), t);
788 }
789 return t;
790 }
791 }
792 if (arg[0] == '-' && arg[1] == '-' && arg[2] == '\0') {
793 /* we found the separator */
794 int j;
795 for (j = GLOBAL_argc - 1; j > i; --j) {
796 t = MkPairTerm(MkAtomTerm(Yap_LookupAtom(GLOBAL_argv[j])), t);
797 }
798 return (t);
799 }
800 i++;
801 }
802 return (t);
803}
804
805static Term mk_os_argc_list(USES_REGS1) {
806 int i = 0;
807 Term t = TermNil;
808 for (i = GLOBAL_argc; i >0; ) {
809 i--;
810 const char *arg = GLOBAL_argv[i];
811 t = MkPairTerm(MkAtomTerm(Yap_LookupAtom(arg)), t);
812 }
813 return (t);
814}
815
816static Term argv(Term inp) {
817 CACHE_REGS
818 return mk_argc_list(PASS_REGS1);
819}
820
821static Term os_argv(Term inp) {
822 CACHE_REGS
823 return mk_os_argc_list(PASS_REGS1);
824}
825
826static FlagEntry *
827GetFlagProp(Atom a) { /* look property list of atom a for kind */
828 AtomEntry *ae = RepAtom(a);
829 FlagEntry *pp;
830
831 READ_LOCK(ae->ARWLock);
832
833 pp = RepFlagProp(ae->PropsOfAE);
834 while (!EndOfPAEntr(pp) && pp->KindOfPE != FlagProperty)
835 pp = RepFlagProp(pp->NextOfPE);
836 READ_UNLOCK(ae->ARWLock);
837
838 return pp;
839}
840
854static void initFlag(flag_info *f, int fnum, bool global) {
855
856 Atom name = Yap_LookupAtom(f->name);
857 AtomEntry *ae = RepAtom(name);
858 WRITE_LOCK(ae->ARWLock);
859 FlagEntry *fprop = RepFlagProp(Yap_GetAPropHavingLock(name, FlagProperty));
860 if (fprop == NULL) {
861 fprop = (FlagEntry *)Yap_AllocAtomSpace(sizeof(FlagEntry));
862 if (fprop == NULL) {
863 WRITE_UNLOCK(ae->ARWLock);
864 Yap_ThrowError(RESOURCE_ERROR_HEAP, TermNil,
865 "not enough space for new Flag %s", ae->StrOfAE);
866 return;
867 }
868 fprop->KindOfPE = FlagProperty;
869 fprop->FlagOfVE = fnum;
870 fprop->rw = f->writable;
871 fprop->global = global;
872 fprop->type = f->def;
873 fprop->helper = f->helper;
874 AddPropToAtom(ae, AbsFlagProp(fprop));
875 }
876 WRITE_UNLOCK(ae->ARWLock);
877}
878
879static Term executable(Term inp) {
880
881 return MkAtomTerm(Yap_LookupAtom(Yap_FindExecutable()));
882}
883
884static Term sys_thread_id(Term inp) {
885 CACHE_REGS
886 int pid;
887#ifdef HAVE_GETTID_SYSCALL
888 pid = syscall(__NR_gettid);
889#elif defined(HAVE_GETTID_MACRO)
890 pid = gettid();
891#elif defined(__WINDOWS__)
892 pid = GetCurrentThreadId();
893#else
894 pid = 0;
895#endif
896
897 return MkIntegerTerm(pid);
898}
899
900static Term sys_pid(Term inp) {
901 CACHE_REGS
902 int pid;
903#if defined(__MINGW32__) || _MSC_VER
904 pid = _getpid();
905#else
906 pid = getpid();
907#endif
908
909 return MkIntegerTerm(pid);
910}
911
912static bool setYapFlagInModule(Term tflag, Term t2, Term mod) {
913 CACHE_REGS
914 FlagEntry *fv;
915 ModEntry *me = Yap_GetModuleEntry(mod);
916 if (!me)
917 return false;
918 fv = GetFlagProp(AtomOfTerm(tflag));
919 if (!fv && !fv->global) {
920 Yap_ThrowError(DOMAIN_ERROR_PROLOG_FLAG, tflag,
921 "trying to set unknown module flag");
922 return false;
923 }
924
925 if (mod == USER_MODULE) {
926 flag_term *tarr = GLOBAL_Flags;
927 if (!(fv->type(t2)))
928 return false;
929
930 if (fv->helper && !(fv->helper(t2)))
931 return false;
932 Term tout = tarr[fv->FlagOfVE].at;
933 if (IsVarTerm(tout)) {
934 Term t;
935 while ((t = Yap_PopTermFromDB(tarr[fv->FlagOfVE].DBT)) == 0) {
936 if (!Yap_dogc()) {
937 Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
938 return false;
939 }
940 }
941 } else if (IsAtomOrIntTerm(t2))
942 tarr[fv->FlagOfVE].at = t2;
943 else {
944 tarr[fv->FlagOfVE].DBT = Yap_StoreTermInDB(t2, 2);
945 }
946 }
947 // module specific stuff now
948
949 if (fv->FlagOfVE == UNKNOWN_FLAG) {
950 me->flags &= ~(UNKNOWN_MASK);
951 if (t2 == TermError) {
952 me->flags |= (UNKNOWN_ERROR);
953 return true;
954 } else if (t2 == TermExit) {
955 me->flags |= (UNKNOWN_ERROR);
956 return true;
957 } else if (t2 == TermFail) {
958 me->flags |= (UNKNOWN_FAIL);
959 return true;
960 } else if (t2 == TermWarning) {
961 me->flags |= (UNKNOWN_WARNING);
962 return true;
963 } else if (t2 == TermFastFail) {
964 me->flags |= (UNKNOWN_FAST_FAIL);
965 return true;
966 }
967 Yap_ThrowError(
968 DOMAIN_ERROR_OUT_OF_RANGE, t2,
969 "bad option %s for unknown flag, use one of error, fail or warning.",
970 RepAtom(AtomOfTerm(tflag))->StrOfAE);
971 return false;
972 } else if (fv->FlagOfVE == DOUBLE_QUOTES_FLAG) {
973 return dqf1(me, t2 PASS_REGS);
974 } else if (fv->FlagOfVE == CHARACTER_ESCAPES_FLAG) {
975 if (t2 == TermTrue) {
976 me->flags |= M_CHARESCAPE;
977 return true;
978 } else if (t2 == TermFalse) {
979 me->flags &= ~(M_CHARESCAPE);
980 return true;
981 }
982 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, t2,
983 "bad option %s for character_escapes flag, use true or false",
984 RepAtom(AtomOfTerm(tflag))->StrOfAE);
985 return false;
986 } else if (fv->FlagOfVE == BACK_QUOTES_FLAG) {
987 return bqf1(me, t2 PASS_REGS);
988 } else if (fv->FlagOfVE == SINGLE_QUOTES_FLAG) {
989 return sqf1(me, t2 PASS_REGS);
990 }
991 // bad key?
992 return false;
993}
994
995static Term getYapFlagInModule(Term tflag, Term mod) {
996 FlagEntry *fv;
997 ModEntry *me = Yap_GetModuleEntry(mod);
998 if (!mod)
999 return false;
1000 fv = GetFlagProp(AtomOfTerm(tflag));
1001 if (!fv && !fv->global) {
1002 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, tflag, "trying to set unknown flag");
1003 return 0L;
1004 }
1005 // module specific stuff now
1006
1007 if (fv->FlagOfVE == UNKNOWN_FLAG) {
1008 if (me->flags & UNKNOWN_ERROR)
1009 return TermError;
1010 if (me->flags & UNKNOWN_WARNING)
1011 return TermWarning;
1012 return TermFail;
1013 } else if (fv->FlagOfVE == CHARACTER_ESCAPES_FLAG) {
1014 if (me->flags & M_CHARESCAPE)
1015 return TermTrue;
1016 } else if (fv->FlagOfVE == BACK_QUOTES_FLAG) {
1017 if (me->flags & BCKQ_CHARS)
1018 return TermChars;
1019 if (me->flags & BCKQ_CODES)
1020 return TermCodes;
1021 if (me->flags & BCKQ_ATOM)
1022 return TermAtom;
1023 return TermString;
1024 } else if (fv->FlagOfVE == SINGLE_QUOTES_FLAG) {
1025 if (me->flags & SNGQ_CHARS)
1026 return TermChars;
1027 if (me->flags & SNGQ_CODES)
1028 return TermCodes;
1029 if (me->flags & SNGQ_ATOM)
1030 return TermAtom;
1031 return TermString;
1032 } else if (fv->FlagOfVE == DOUBLE_QUOTES_FLAG) {
1033 if (me->flags & DBLQ_CHARS)
1034 return TermChars;
1035 if (me->flags & DBLQ_CODES)
1036 return TermCodes;
1037 if (me->flags & DBLQ_ATOM)
1038 return TermAtom;
1039 return TermString;
1040 }
1041 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, tflag, "flag %s is not module-scoped",
1042 RepAtom(AtomOfTerm(tflag))->StrOfAE);
1043 return 0L;
1044}
1045
1046static Int cont_yap_flag(USES_REGS1) {
1047 int i = IntOfTerm(EXTRA_CBACK_ARG(2, 1));
1048 int gmax = GLOBAL_flagCount;
1049 int lmax = LOCAL_flagCount;
1050 Term tflag = Deref(ARG1);
1051 EXTRA_CBACK_ARG(2, 1) = MkIntTerm(i + 1);
1052
1053 if (IsApplTerm(tflag) && FunctorOfTerm(tflag) == FunctorModule) {
1054 Term modt = CurrentModule;
1055 tflag = Yap_StripModule(tflag, &modt);
1056 while (i != gmax && i != UNKNOWN_FLAG && i != CHARACTER_ESCAPES_FLAG &&
1057 i != BACK_QUOTES_FLAG && i != SINGLE_QUOTES_FLAG &&
1058 i != DOUBLE_QUOTES_FLAG)
1059 i++;
1060 if (i == gmax)
1061 cut_fail();
1062 EXTRA_CBACK_ARG(2, 1) = MkIntTerm(i + 1);
1063 {
1064 Term lab = MkAtomTerm(Yap_LookupAtom(global_flags_setup[i].name));
1065 Term val = Deref(ARG2);
1066
1067 if (!Yap_unify(tflag, lab))
1068 return false;
1069 if (IsVarTerm(val)) {
1070 Term oval = getYapFlagInModule(lab, modt);
1071 if (oval == 0)
1072 return false;
1073 return Yap_unify(oval, val);
1074 } else {
1075 return setYapFlagInModule(tflag, val, modt);
1076 }
1077 }
1078 return false;
1079 }
1080 if (i >= gmax) {
1081 Yap_unify(ARG1,
1082 MkAtomTerm(Yap_LookupAtom(local_flags_setup[i - gmax].name)));
1083 if (i == gmax + lmax - 1)
1084 do_cut(0);
1085 } else {
1086 Yap_unify(ARG1, MkAtomTerm(Yap_LookupAtom(global_flags_setup[i].name)));
1087 }
1088 Term flag = getYapFlag(Deref(ARG1));
1089 return Yap_unify(flag, ARG2);
1090}
1091
1092/* yap_flag( ?Key, ? CurrentValue, ?NewValue)
1093 *
1094 * Atomically read and set a flag _Key_. It is useful to temporarily set a flag, eg:
1095 * ~~~~
1096 * main :-
1097 * yap_flag(key,DefaultValue,TemporaryValue),
1098 * code,
1099 * yap_flag(key, _, DefaultValue),
1100 * ~~~
1101 *
1102 * The predicate is very similar to current_prolog_flag/3. We suggest using yap_flag/3 only for yap specific flags.
1103 */
1104static Int yap_flag(USES_REGS1) {
1105 Term tflag = Deref(ARG1);
1106 Term val = Deref(ARG2);
1107 if (IsVarTerm(tflag)) {
1108 EXTRA_CBACK_ARG(2, 1) = MkIntTerm(0);
1109 return cont_yap_flag(PASS_REGS1);
1110 }
1111 if (IsApplTerm(tflag) && FunctorOfTerm(tflag) == FunctorModule) {
1112 Term modt;
1113 tflag = Yap_StripModule(tflag, &modt);
1114 if (IsVarTerm(tflag)) {
1115 EXTRA_CBACK_ARG(2, 1) = MkIntTerm(0);
1116 return cont_yap_flag(PASS_REGS1);
1117 }
1118 do_cut(0);
1119
1120 if (!isatom(tflag))
1121 return false;
1122 if (!isatom(modt))
1123 return false;
1124 if (IsVarTerm(val)) {
1125 Term flag = getYapFlagInModule(tflag, modt);
1126 if (flag == 0)
1127 return false;
1128 return Yap_unify(flag, ARG2);
1129 } else {
1130 return setYapFlagInModule(tflag, val, modt);
1131 }
1132 }
1133 do_cut(0);
1134 /*
1135 * if (Deref(ARG1) == MkAtomTerm(Yap_LookupAtom("verbose_load"))) {
1136 * Yap_DebugPlWriteln(ARG2); Yap_DebugPlWriteln(ARG3);
1137 * }
1138 */
1139 Term flag = getYapFlag(tflag);
1140 if (flag == 0)
1141 return false;
1142 if (! Yap_unify(flag, val) )
1143 return false;
1144 return Yap_set_flag(tflag, Deref(ARG3) PASS_REGS1);
1145}
1146
1147static Int cont_prolog_flag(USES_REGS1) {
1148 int i = IntOfTerm(EXTRA_CBACK_ARG(3, 1));
1149 while (i < GLOBAL_flagCount + LOCAL_flagCount) {
1150 int gmax = GLOBAL_flagCount;
1151 int lmax = LOCAL_flagCount;
1152 Term flag, f;
1153
1154 if (i >= gmax + lmax) {
1155 cut_fail();
1156 } else if (i >= gmax) {
1157 Yap_unify(ARG1, (f = MkAtomTerm(
1158 Yap_LookupAtom(local_flags_setup[i - gmax].name))));
1159 } else {
1160 Yap_unify(ARG1,
1161 (f = MkAtomTerm(Yap_LookupAtom(global_flags_setup[i].name))));
1162 }
1163 EXTRA_CBACK_ARG(3, 1) = MkIntTerm(++i);
1164 flag = getYapFlag(f);
1165 if (!Yap_unify(flag, ARG2))
1166 return false;
1167 return Yap_set_flag(f, Deref(ARG3));
1168 }
1169 cut_fail();
1170}
1171
1172
1173
1174/* @pred yap_flag( ?Key, ? Value)
1175 *
1176 * If _Value_ is bound, set the flag _Key_; if unbound unify _Value_ with it's value. Consider using get_prolog_flag/2 and
1177 * set_prolog_flag/2.
1178 *
1179 */
1180static Int yap_flag2(USES_REGS1) {
1181 ARG3 = ARG2;
1182 if (!IsVarTerm(Deref(ARG2))) {
1183 ARG2 = MkVarTerm();
1184 }
1185 return yap_flag(PASS_REGS);
1186}
1187
1197static Int prolog_flag(USES_REGS1) {
1198 if (IsVarTerm(Deref(ARG1))) {
1199 EXTRA_CBACK_ARG(3, 1) = MkIntTerm(0);
1200 return cont_prolog_flag(PASS_REGS1);
1201 }
1202 do_cut(0);
1203 if (IsVarTerm(Deref(ARG3))) {
1204 Term flag = getYapFlag(Deref(ARG1));
1205 if (flag == 0)
1206 return false;
1207 return Yap_unify(flag, ARG2);
1208 }
1209 return Yap_set_flag(Deref(ARG1), Deref(ARG3));
1210}
1211
1212static Int cont_current_prolog_flag(USES_REGS1) {
1213 int i = IntOfTerm(EXTRA_CBACK_ARG(2, 1));
1214 while (i < GLOBAL_flagCount + LOCAL_flagCount) {
1215 int gmax = GLOBAL_flagCount;
1216 int lmax = LOCAL_flagCount;
1217 Term flag, f;
1218
1219 if (i >= gmax + lmax) {
1220 cut_fail();
1221 } else if (i >= gmax) {
1222 Yap_unify(ARG1, (f = MkAtomTerm(
1223 Yap_LookupAtom(local_flags_setup[i - gmax].name))));
1224 } else {
1225 Yap_unify(ARG1,
1226 (f = MkAtomTerm(Yap_LookupAtom(global_flags_setup[i].name))));
1227 }
1228 EXTRA_CBACK_ARG(2, 1) = MkIntTerm(++i);
1229 flag = getYapFlag(f);
1230 return Yap_unify(flag, ARG2);
1231 }
1232 cut_fail();
1233}
1234
1240static Int current_prolog_flag(USES_REGS1) {
1241 if (IsVarTerm(Deref(ARG1))) {
1242 EXTRA_CBACK_ARG(3, 1) = MkIntTerm(0);
1243 return cont_current_prolog_flag(PASS_REGS1);
1244 }
1245 do_cut(0);
1246 Term flag = getYapFlag(Deref(ARG1));
1247 if (flag == 0)
1248 return false;
1249 return Yap_unify(flag, ARG2);
1250}
1251
1259static Int current_prolog_flag2(USES_REGS1) {
1260 Term tflag = Deref(ARG1);
1261 Term tout = 0;
1262 FlagEntry *fv;
1263 flag_term *tarr;
1264
1265 if (IsVarTerm(tflag)) {
1266 EXTRA_CBACK_ARG(2, 1) = MkIntTerm(0);
1267 return cont_yap_flag(PASS_REGS1);
1268 }
1269 do_cut(0);
1270 if (IsStringTerm(tflag)) {
1271 tflag = MkStringTerm(RepAtom(AtomOfTerm(tflag))->StrOfAE);
1272 }
1273 if (!IsAtomTerm(tflag)) {
1274 Yap_ThrowError(TYPE_ERROR_ATOM, tflag, "current_prolog_flag/3");
1275 return (FALSE);
1276 }
1277 fv = GetFlagProp(AtomOfTerm(tflag));
1278 if (!fv) {
1279 // should itself depend on a flag
1280 return FALSE;
1281 }
1282 if (fv->global)
1283 tarr = GLOBAL_Flags;
1284 else
1285 tarr = LOCAL_Flags;
1286 tout = tarr[fv->FlagOfVE].at;
1287 if (tout == TermZERO) {
1288 // Yap_DebugPlWriteln(tflag);
1289 return false;
1290 }
1291 if (!IsAtomicTerm(tout)) {
1292 while ((tout = Yap_FetchTermFromDB(tarr[fv->FlagOfVE].DBT)) == 0) {
1293 /* oops, we are in trouble, not enough stack space */
1294 if (LOCAL_Error_TYPE == RESOURCE_ERROR_ATTRIBUTED_VARIABLES) {
1295 LOCAL_Error_TYPE = YAP_NO_ERROR;
1296 if (!Yap_growglobal(NULL)) {
1297 Yap_ThrowError(RESOURCE_ERROR_ATTRIBUTED_VARIABLES, TermNil,
1298 LOCAL_ErrorMessage);
1299 UNLOCK(ap->PELock);
1300 return false;
1301 }
1302 } else {
1303 LOCAL_Error_TYPE = YAP_NO_ERROR;
1304 if (!Yap_dogc()) {
1305 Yap_ThrowError(RESOURCE_ERROR_STACK, TermNil, LOCAL_ErrorMessage);
1306 UNLOCK(ap->PELock);
1307 return false;
1308 }
1309 }
1310 }
1311 }
1312 return (Yap_unify(ARG2, tout));
1313}
1314
1315void Yap_setModuleFlags(ModEntry *new, ModEntry *cme) {
1316 CACHE_REGS
1317
1318 Atom at = new->AtomOfME;
1319 if (at == AtomProlog || CurrentModule == PROLOG_MODULE) {
1320 new->flags = M_SYSTEM | UNKNOWN_ERROR | M_CHARESCAPE | DBLQ_CODES |
1321 BCKQ_STRING | SNGQ_ATOM;
1322 if (at == AtomUser)
1323 new->flags =
1324 UNKNOWN_ERROR | M_CHARESCAPE | DBLQ_CODES | BCKQ_STRING | SNGQ_ATOM;
1325 } else if (cme && cme->flags && cme != new) {
1326 new->flags = cme->flags;
1327 } else {
1328 new->flags =
1329 (UNKNOWN_ERROR | M_CHARESCAPE | DBLQ_CODES | BCKQ_STRING | SNGQ_ATOM);
1330 }
1331 // printf("cme=%s new=%s flags=%x\n",cme,at->StrOfAE,new->flags);
1332}
1333
1334bool Yap_set_flag(Term tflag, Term t2) {
1335 FlagEntry *fv;
1336 flag_term *tarr;
1337 tflag = Deref(tflag);
1338 t2 = Deref(t2);
1339 if (IsVarTerm(tflag)) {
1340 Yap_ThrowError(INSTANTIATION_ERROR, tflag, "yap_flag/2");
1341 return (FALSE);
1342 }
1343 if (IsStringTerm(tflag)) {
1344 tflag = MkStringTerm(RepAtom(AtomOfTerm(tflag))->StrOfAE);
1345 }
1346
1347 if (IsApplTerm(tflag) && FunctorOfTerm(tflag) == FunctorModule) {
1348 Term modt;
1349 tflag = Yap_StripModule(tflag, &modt);
1350 if (!isatom(tflag))
1351 return false;
1352 if (!isatom(modt))
1353 return false;
1354 return setYapFlagInModule(tflag, t2, modt);
1355 }
1356 if (!IsAtomTerm(tflag)) {
1357 Yap_ThrowError(TYPE_ERROR_ATOM, tflag, "yap_flag/2");
1358 return (FALSE);
1359 }
1360 fv = GetFlagProp(AtomOfTerm(tflag));
1361 if (!fv) {
1362 Term fl = GLOBAL_Flags[USER_FLAGS_FLAG].at;
1363 if (fl == TermSilent) {
1364 CACHE_REGS
1365 Term t2 = Deref(ARG2);
1366 newFlag(tflag, t2);
1367 } else if (fl == TermWarning) {
1368 Yap_Warning("Flag %s does not exist", RepAtom(AtomOfTerm(fl))->StrOfAE);
1369 } else {
1370 Yap_ThrowError(DOMAIN_ERROR_PROLOG_FLAG, tflag,
1371 "trying to set unknown flag \"%s\"",
1372 AtomName(AtomOfTerm(tflag)));
1373 }
1374 return false;
1375 }
1376 if (fv->global) {
1377 CACHE_REGS
1378 switch (fv->FlagOfVE) {
1379 case UNKNOWN_FLAG:
1380 case CHARACTER_ESCAPES_FLAG:
1381 case BACK_QUOTES_FLAG:
1382 case DOUBLE_QUOTES_FLAG:
1383 case SINGLE_QUOTES_FLAG:
1384 return setYapFlagInModule(tflag, t2, CurrentModule);
1385 default:
1386 tarr = GLOBAL_Flags;
1387 }
1388 } else {
1389 CACHE_REGS
1390 tarr = LOCAL_Flags;
1391 }
1392 if (!(t2 = fv->type(t2)))
1393 return false;
1394 if (fv->helper && !(fv->helper(t2)))
1395 return false;
1396 Term tout = tarr[fv->FlagOfVE].at;
1397 if (IsVarTerm(tout))
1398 Yap_PopTermFromDB(tarr[fv->FlagOfVE].DBT);
1399 if (IsAtomOrIntTerm(t2))
1400 tarr[fv->FlagOfVE].at = t2;
1401 else {
1402 tarr[fv->FlagOfVE].DBT = Yap_StoreTermInDB(t2, 2);
1403 }
1404 return true;
1405}
1406
1407Term Yap_UnknownFlag(Term mod) {
1408 if (mod == PROLOG_MODULE)
1409 mod = TermProlog;
1410
1411 ModEntry *fv = Yap_GetModuleEntry(mod);
1412 if (fv == NULL)
1413 fv = Yap_GetModuleEntry(TermUser);
1414 if (fv->flags & UNKNOWN_ERROR)
1415 return TermError;
1416 if (fv->flags & UNKNOWN_WARNING)
1417 return TermWarning;
1418 return TermFail;
1419}
1420
1421Term getYapFlag(Term tflag) {
1422 FlagEntry *fv;
1423 flag_term *tarr;
1424 tflag = Deref(tflag);
1425 if (IsVarTerm(tflag)) {
1426 Yap_ThrowError(INSTANTIATION_ERROR, tflag, "yap_flag/2");
1427 return (FALSE);
1428 }
1429 if (IsStringTerm(tflag)) {
1430 tflag = MkStringTerm(RepAtom(AtomOfTerm(tflag))->StrOfAE);
1431 }
1432 if (IsApplTerm(tflag) && FunctorOfTerm(tflag) == FunctorModule) {
1433 Term modt;
1434 tflag = Yap_StripModule(tflag, &modt);
1435 if (IsStringTerm(tflag)) {
1436 tflag = MkStringTerm(RepAtom(AtomOfTerm(tflag))->StrOfAE);
1437 }
1438 if (!isatom(tflag))
1439 return false;
1440 if (IsStringTerm(modt)) {
1441 modt = MkStringTerm(RepAtom(AtomOfTerm(modt))->StrOfAE);
1442 }
1443 if (!isatom(modt))
1444 return false;
1445 return getYapFlagInModule(tflag, modt);
1446 }
1447 if (!IsAtomTerm(tflag)) {
1448 Yap_ThrowError(TYPE_ERROR_ATOM, tflag, "yap_flag/2");
1449 return (FALSE);
1450 }
1451 if (tflag == TermSilent)
1452 {
1453 Yap_DebugPlWriteln(TermSilent);
1454 }
1455 fv = GetFlagProp(AtomOfTerm(tflag));
1456 if (!fv) {
1457 Term fl = GLOBAL_Flags[USER_FLAGS_FLAG].at;
1458 if (fl == TermSilent) {
1459 return false;
1460 } else if (fl == TermWarning) {
1461 Yap_Warning("Flag ~s does not exist",
1462 RepAtom(AtomOfTerm(tflag))->StrOfAE);
1463 } else {
1464 Yap_ThrowError(DOMAIN_ERROR_PROLOG_FLAG, tflag,
1465 "trying to use unknown flag %s",
1466 RepAtom(AtomOfTerm(tflag))->StrOfAE);
1467 }
1468 return false;
1469 }
1470 if (fv->global)
1471 tarr = GLOBAL_Flags;
1472 else {
1473 CACHE_REGS
1474 tarr = LOCAL_Flags;
1475 }
1476 Term tout = tarr[fv->FlagOfVE].at;
1477 if (IsVarTerm(tout))
1478 return Yap_FetchTermFromDB(tarr[fv->FlagOfVE].DBT);
1479 else
1480 return tout;
1481}
1482
1489static Int set_prolog_flag(USES_REGS1) {
1490 Term tflag = Deref(ARG1), t2 = Deref(ARG2);
1491 return Yap_set_flag(tflag, t2);
1492}
1493
1504static Int source(USES_REGS1) {
1505 setBooleanGlobalPrologFlag(SOURCE_FLAG, true);
1506 return true;
1507}
1508
1515static Int no_source(USES_REGS1) {
1516 setBooleanGlobalPrologFlag(SOURCE_FLAG, false);
1517 return true;
1518}
1519
1529static Int source_mode(USES_REGS1) {
1530 Term targ;
1531 bool current = trueGlobalPrologFlag(SOURCE_FLAG);
1532 if (current && !Yap_unify_constant(ARG1, TermTrue))
1533 return false;
1534 if (!current && !Yap_unify_constant(ARG1, TermFalse))
1535 return false;
1536 targ = Deref(ARG2);
1537 Yap_set_flag(TermSource, targ);
1538 return true;
1539}
1540
1541static bool setInitialValue(bool bootstrap, flag_func f, const char *s,
1542 flag_term *tarr) {
1543 errno = 0;
1544 const char *ss = (const char *)s;
1545
1546 if (f == booleanFlag) {
1547 if (!bootstrap) {
1548 return 0;
1549 }
1550 const char *ss = (const char *)s;
1551 if (!strcmp(ss, "true")) {
1552 tarr->at = TermTrue;
1553 return true;
1554 }
1555 if (!strcmp(ss, "false")) {
1556 tarr->at = TermFalse;
1557 return true;
1558 }
1559 if (!strcmp(ss, "on")) {
1560 tarr->at = TermTrue;
1561 return true;
1562 }
1563 if (!strcmp(ss, "off")) {
1564 tarr->at = TermFalse;
1565 return true;
1566 }
1567 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, TermNil,
1568 "~s should be either true (on) or false (off)", s);
1569 return false;
1570 } else if (f == nat) {
1571 if (!bootstrap) {
1572 return 0;
1573 }
1574 UInt r = strtoul(ss, NULL, 10);
1575 Term t;
1576 if (errno) {
1577 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, TermNil,
1578 "~s should be a positive integer)", s);
1579 return false;
1580 }
1581 CACHE_REGS
1582 t = MkIntegerTerm(r);
1583 if (IsIntTerm(t))
1584 tarr->at = t;
1585 else {
1586 tarr->DBT = Yap_StoreTermInDB(t, 2);
1587 }
1588 return true;
1589 } else if (f == at2n) {
1590 if (!bootstrap) {
1591 return false;
1592 }
1593 if (!strcmp(ss, "INT_MAX")) {
1594 tarr->at = MkIntTerm(Int_MAX);
1595 return true;
1596 }
1597 if (!strcmp(ss, "MAX_THREADS")) {
1598 tarr->at = MkIntTerm(MAX_THREADS);
1599 return true;
1600 }
1601 if (!strcmp(ss, "MAX_WORKERS")) {
1602 tarr->at = MkIntTerm(MAX_WORKERS);
1603 return true;
1604 }
1605 if (!strcmp(ss, "INT_MIN")) {
1606 tarr->at = MkIntTerm(Int_MIN);
1607 return true;
1608 }
1609 if (!strcmp(ss, "YAP_NUMERIC_VERSION")) {
1610 tarr->at = MkIntTerm(atol(YAP_NUMERIC_VERSION));
1611 return true;
1612 }
1613 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, TermNil,
1614 "~s should be either true (on) or false (off)", s);
1615 return false;
1616 } else if (f == isatom) {
1617 if (!bootstrap) {
1618 return false;
1619 }
1620 Atom r = Yap_LookupAtom(s);
1621 if (errno) {
1622 Yap_ThrowError(DOMAIN_ERROR_OUT_OF_RANGE, TermNil,
1623 "~s should be a positive integer)", s);
1624 tarr->at = TermNil;
1625 }
1626 tarr->at = MkAtomTerm(r);
1627 return true;
1628 } else if (f == options) {
1629 CACHE_REGS
1630 char tmp[512];
1631 Term t0;
1632 if (bootstrap) {
1633 return true;
1634 }
1635 t0 = AbsPair(HR);
1636 while (true) {
1637 int i = 0, ch = s[0];
1638 while (ch != '\0' && ch != ';') {
1639 if (ch != ' ')
1640 tmp[i++] = ch;
1641 s++;
1642 ch = *s;
1643 }
1644 tmp[i] = '\0';
1645 HR += 2;
1646 HR[-2] = MkAtomTerm(Yap_LookupAtom(tmp));
1647 if (ch) {
1648 HR[-1] = AbsPair(HR);
1649 s++;
1650 continue;
1651 } else {
1652 HR[-1] = TermNil;
1653 tarr->DBT = Yap_StoreTermInDB(t0, 2);
1654 return true;
1655 }
1656 }
1657 } else if (strcmp(ss, "@boot") == 0) {
1658 if (bootstrap) {
1659 return true;
1660 }
1661
1662 Term t = f(TermZERO);
1663 if (t == TermZERO)
1664 return false;
1665 if (IsAtomOrIntTerm(t)) {
1666 tarr->at = t;
1667 } else {
1668 tarr->DBT = Yap_StoreTermInDB(t, 2);
1669 }
1670
1671 } else {
1672 Term t0;
1673 if (bootstrap) {
1674 return false;
1675 }
1676 CACHE_REGS
1677 const char *us = (const char *)s;
1678 t0 = Yap_BufferToTermWithPrioBindings(us, TermNil, 0L, strlen(s) + 1,
1679 GLOBAL_MaxPriority);
1680 if (!t0)
1681 return false;
1682 if (IsStringTerm(t0)) {
1683 t0 = MkStringTerm(RepAtom(AtomOfTerm(t0))->StrOfAE);
1684 }
1685 if (IsAtomTerm(t0) || IsIntTerm(t0)) {
1686 // do yourself flags
1687 if (t0 == MkAtomTerm(AtomQuery)) {
1688 f(TermNil);
1689 } else {
1690 tarr->at = t0;
1691 }
1692 } else {
1693 tarr->DBT = Yap_StoreTermInDB(t0, 2);
1694 }
1695 return true;
1696 }
1697 return false;
1698}
1699
1700#undef PAR
1701
1702#define PROLOG_FLAG_PROPERTY_DEFS() \
1703 PAR("access", isaccess, PROLOG_FLAG_PROPERTY_ACCESS, "read_write") \
1704 , PAR("type", isground, PROLOG_FLAG_PROPERTY_TYPE, "term"), \
1705 PAR("scope", flagscope, PROLOG_FLAG_PROPERTY_SCOPE, "global"), \
1706 PAR("keep", booleanFlag, PROLOG_FLAG_PROPERTY_KEEP, "false"), \
1707 PAR(NULL, ok, PROLOG_FLAG_PROPERTY_END, 0)
1708
1709#define PAR(x, y, z, w) z
1710
1711typedef enum prolog_flag_property_enum_choices {
1712 PROLOG_FLAG_PROPERTY_DEFS()
1713} prolog_flag_property_choices_t;
1714
1715#undef PAR
1716
1717#define PAR(x, y, z, w) \
1718 { x, y, z, w }
1719
1720static const param2_t prolog_flag_property_defs[] = {
1721 PROLOG_FLAG_PROPERTY_DEFS()};
1722#undef PAR
1723
1724static Int
1725do_prolog_flag_property(Term tflag,
1726 Term opts USES_REGS) { /* Init current_prolog_flag */
1727 FlagEntry *fv;
1728 xarg *args;
1729 prolog_flag_property_choices_t i;
1730 bool rc = true;
1731 args =
1732 Yap_ArgList2ToVector(opts, prolog_flag_property_defs,
1733 PROLOG_FLAG_PROPERTY_END, DOMAIN_ERROR_PROLOG_FLAG);
1734 if (args == NULL) {
1735 Yap_ThrowError(LOCAL_Error_TYPE, opts, NULL);
1736 return false;
1737 }
1738 Atom atflag;
1739 Term modt = CurrentModule;
1740 tflag = Yap_YapStripModule(tflag, &modt);
1741 if (IsStringTerm(tflag)) {
1742 atflag = Yap_LookupAtom(StringOfTerm(tflag));
1743 } else if (IsAtomTerm(tflag)) {
1744 atflag = AtomOfTerm(tflag);
1745 } else {
1746 free(args);
1747 Yap_ThrowError(TYPE_ERROR_ATOM, tflag, "yap_flag/2");
1748 return (FALSE);
1749 }
1750 fv = GetFlagProp(atflag);
1751 if (!fv)
1752 return false;
1753 //Yap_ThrowError(DOMAIN_ERROR_PROLOG_FLAG,MkAtomTerm(atflag),NULL);
1754 for (i = 0; i < PROLOG_FLAG_PROPERTY_END; i++) {
1755 if (args[i].used) {
1756 switch (i) {
1757 case PROLOG_FLAG_PROPERTY_ACCESS:
1758 if (fv->rw)
1759 rc = rc && Yap_unify(TermReadWrite,
1760 args[PROLOG_FLAG_PROPERTY_ACCESS].tvalue);
1761 else
1762 rc = rc && Yap_unify(TermReadOnly,
1763 args[PROLOG_FLAG_PROPERTY_ACCESS].tvalue);
1764 break;
1765 case PROLOG_FLAG_PROPERTY_TYPE:
1766 if (fv->type == booleanFlag)
1767 rc = rc &&
1768 Yap_unify(TermBoolean, args[PROLOG_FLAG_PROPERTY_TYPE].tvalue);
1769 else if (fv->type == isatom)
1770 rc =
1771 rc && Yap_unify(TermAtom, args[PROLOG_FLAG_PROPERTY_TYPE].tvalue);
1772 else if (fv->type == nat)
1773 rc = rc &&
1774
1775 Yap_unify(TermInteger, args[PROLOG_FLAG_PROPERTY_TYPE].tvalue);
1776 else if (fv->type == isfloat)
1777 rc = rc &&
1778 Yap_unify(TermFloat, args[PROLOG_FLAG_PROPERTY_TYPE].tvalue);
1779 else
1780 rc =
1781 rc && Yap_unify(TermTerm, args[PROLOG_FLAG_PROPERTY_TYPE].tvalue);
1782 break;
1783 case PROLOG_FLAG_PROPERTY_KEEP:
1784 rc = rc && false;
1785 break;
1786 case PROLOG_FLAG_PROPERTY_SCOPE:
1787 if (fv->global) {
1788 if (fv->FlagOfVE == UNKNOWN_FLAG ||
1789 fv->FlagOfVE == CHARACTER_ESCAPES_FLAG ||
1790 fv->FlagOfVE == SINGLE_QUOTES_FLAG ||
1791 fv->FlagOfVE == DOUBLE_QUOTES_FLAG ||
1792 fv->FlagOfVE == BACK_QUOTES_FLAG)
1793 Yap_unify(TermModule, args[PROLOG_FLAG_PROPERTY_SCOPE].tvalue);
1794 rc = rc &&
1795 Yap_unify(TermGlobal, args[PROLOG_FLAG_PROPERTY_SCOPE].tvalue);
1796 } else
1797 rc = rc &&
1798 Yap_unify(TermThread, args[PROLOG_FLAG_PROPERTY_SCOPE].tvalue);
1799 break;
1800 case PROLOG_FLAG_PROPERTY_END:
1801 /* break; */
1802 Yap_ThrowError(DOMAIN_ERROR_PROLOG_FLAG, opts, "Flag not supported by YAP");
1803 }
1804 }
1805 }
1806 // UNLOCK(GLOBAL_Prolog_Flag[sno].prolog_flaglock);
1807 free(args);
1808 return rc;
1809}
1810
1811static Int cont_prolog_flag_property(USES_REGS1) { /* current_prolog_flag */
1812 int i = IntOfTerm(EXTRA_CBACK_ARG(2, 1));
1813
1814 while (i < GLOBAL_flagCount + LOCAL_flagCount) {
1815 int gmax = GLOBAL_flagCount;
1816 int lmax = LOCAL_flagCount;
1817 Term lab;
1818
1819 if (i >= gmax + lmax) {
1820 cut_fail();
1821 } else if (i >= gmax) {
1822 lab = MkAtomTerm(Yap_LookupAtom(local_flags_setup[i - gmax].name));
1823 } else {
1824 if (i == UNKNOWN_FLAG || i == CHARACTER_ESCAPES_FLAG ||
1825 i == SINGLE_QUOTES_FLAG || i == DOUBLE_QUOTES_FLAG ||
1826 i == BACK_QUOTES_FLAG) {
1827 Term labs[2];
1828 labs[0] = MkVarTerm();
1829 labs[1] = MkAtomTerm(Yap_LookupAtom(global_flags_setup[i].name));
1830 lab = Yap_MkApplTerm(FunctorModule, 2, labs);
1831 } else {
1832 lab = MkAtomTerm(Yap_LookupAtom(global_flags_setup[i].name));
1833 }
1834 }
1835 EXTRA_CBACK_ARG(2, 1) = MkIntTerm(++i);
1836 Yap_unify(ARG1, lab);
1837 return do_prolog_flag_property(lab, Deref(ARG2) PASS_REGS);
1838 }
1839 cut_fail();
1840}
1841
1855static Int prolog_flag_property(USES_REGS1) { /* Initc urrent_prolog_flag */
1856 Term t1 = Deref(ARG1);
1857 /* make valgrind happy by always filling in memory */
1858 EXTRA_CBACK_ARG(2, 1) = MkIntTerm(0);
1859 if (IsStringTerm(t1)) {
1860 t1 = MkStringTerm(RepAtom(AtomOfTerm(t1))->StrOfAE);
1861 }
1862 if (IsVarTerm(t1)) {
1863 return (cont_prolog_flag_property(PASS_REGS1));
1864 } else {
1865 if (IsApplTerm(t1) && FunctorOfTerm(t1) == FunctorModule) {
1866 Term modt;
1867 t1 = Yap_StripModule(t1, &modt);
1868 if (IsAtomTerm(modt)) {
1869 Int rc;
1870 rc = cont_prolog_flag_property(PASS_REGS1);
1871
1872 return rc;
1873 }
1874 } else if (IsAtomTerm(t1)) {
1875 do_cut(0);
1876 return do_prolog_flag_property(t1, Deref(ARG2) PASS_REGS);
1877 } else {
1878 Yap_ThrowError(TYPE_ERROR_ATOM, t1, "prolog_flag_property/2");
1879 }
1880 }
1881 return false;
1882}
1883
1884static void newFlag(Term fl, Term val) {
1885 flag_info f;
1886 int i = GLOBAL_flagCount;
1887
1888 GLOBAL_flagCount++;
1889 f.name = (char *)RepAtom(AtomOfTerm(fl))->StrOfAE;
1890 f.writable = true;
1891 f.helper = NULL;
1892 f.def = ok;
1893 initFlag(&f, i, true);
1894 if (IsAtomOrIntTerm(val)) {
1895 GLOBAL_Flags[i].at = val;
1896 } else {
1897 GLOBAL_Flags[i].DBT = Yap_StoreTermInDB(val, 2);
1898 }
1899}
1900
1901static Int do_create_prolog_flag(USES_REGS1) {
1902 FlagEntry *fv;
1903 xarg *args;
1904 prolog_flag_property_choices_t i;
1905 Term tflag = Deref(ARG1), tval = Deref(ARG2), opts = Deref(ARG3);
1906
1907 args =
1908 Yap_ArgList2ToVector(opts, prolog_flag_property_defs,
1909 PROLOG_FLAG_PROPERTY_END, DOMAIN_ERROR_PROLOG_FLAG);
1910 if (args == NULL) {
1911 Yap_ThrowError(LOCAL_Error_TYPE, opts, NULL);
1912 return false;
1913 }
1914 fv = GetFlagProp(AtomOfTerm(tflag));
1915 if (fv) {
1916 if (args[PROLOG_FLAG_PROPERTY_KEEP].used &&
1917 args[PROLOG_FLAG_PROPERTY_KEEP].tvalue == TermTrue) {
1918 free(args);
1919 return true;
1920 }
1921 } else {
1922 newFlag(tflag, tval);
1923 fv = GetFlagProp(AtomOfTerm(tflag));
1924 }
1925 for (i = 0; i < PROLOG_FLAG_PROPERTY_END; i++) {
1926 if (args[i].used) {
1927 switch (i) {
1928 case PROLOG_FLAG_PROPERTY_KEEP:
1929 break;
1930 case PROLOG_FLAG_PROPERTY_ACCESS:
1931 if (args[PROLOG_FLAG_PROPERTY_ACCESS].tvalue == TermReadWrite)
1932 fv->rw = true;
1933 else
1934 fv->rw = false;
1935 break;
1936 case PROLOG_FLAG_PROPERTY_TYPE: {
1937 Term ttype = args[PROLOG_FLAG_PROPERTY_TYPE].tvalue;
1938 if (ttype == TermBoolean)
1939 fv->type = booleanFlag;
1940 else if (ttype == TermInteger)
1941 fv->type = isatom;
1942 else if (ttype == TermFloat)
1943 fv->type = isfloat;
1944 else
1945 fv->type = isground;
1946 } break;
1947 case PROLOG_FLAG_PROPERTY_SCOPE:
1948 free(args);
1949 return false;
1950 case PROLOG_FLAG_PROPERTY_END:
1951 break;
1952 }
1953 }
1954 }
1955 // UNLOCK(GLOBAL_Prolog_Flag[sno].prolog_flaglock);
1956 free(args);
1957 return true;
1958}
1959
1968X_API bool Yap_create_prolog_flag(const char *name, bool writable, Term ttype, Term v) {
1969
1970 Atom aname = Yap_LookupAtom (name);
1971 FlagEntry *fv;
1972 fv = GetFlagProp(aname);
1973 if (fv) {
1974 return false;
1975 } else {
1976 newFlag(MkAtomTerm(aname), v);
1977 fv = GetFlagProp(aname);
1978 }
1979 fv->rw = writable;
1980 if (ttype == TermBoolean)
1981 fv->type = booleanFlag;
1982 else if (ttype == TermInteger)
1983 fv->type = isatom;
1984 else if (ttype == TermFloat)
1985 fv->type = isfloat;
1986 else
1987 fv->type = isground;
1988 return true;
1989 }
1990
2002void Yap_InitFlags(bool bootstrap) {
2003 CACHE_REGS
2004 tr_fr_ptr tr0 = TR;
2005 flag_info *f = global_flags_setup;
2006 int lvl = push_text_stack();
2007 char *buf = Malloc(4098);
2008 GLOBAL_flagCount = 0;
2009 if (bootstrap) {
2010 GLOBAL_Flags = (union flagTerm *)Yap_AllocCodeSpace(
2011 sizeof(union flagTerm) *
2012 (2 * sizeof(global_flags_setup) / sizeof(flag_info)));
2013 }
2014 while (f->name != NULL) {
2015 bool itf = setInitialValue(bootstrap, f->def, f->init,
2016 GLOBAL_Flags + GLOBAL_flagCount);
2017 if (itf) {
2018 initFlag(f, GLOBAL_flagCount, true);
2019 }
2020 GLOBAL_flagCount++;
2021 f++;
2022 }
2023 LOCAL_flagCount = 0;
2024 int nflags = sizeof(local_flags_setup) / sizeof(flag_info);
2025 if (bootstrap)
2026 LOCAL_Flags =
2027 (union flagTerm *)Yap_AllocCodeSpace(sizeof(union flagTerm) * nflags);
2028 f = local_flags_setup;
2029 while (f->name != NULL) {
2030 char *s;
2031 if (f->init == NULL || f->init[0] == '\0') s = NULL;
2032 else if (strlen(f->init) < 4096) {
2033 s = buf;
2034 strcpy(buf, f->init);
2035 } else {
2036 s = Malloc(strlen(f->init)+1);
2037 strcpy(s, f->init);
2038 }
2039 bool itf = setInitialValue(bootstrap, f->def, s,
2040 LOCAL_Flags + LOCAL_flagCount);
2041 // Term itf = Yap_BufferToTermWithPrioBindings(f->init,
2042 // strlen(f->init)+1,
2043 // LOBAL_MaxPriority, &tp);
2044 if (itf) {
2045 initFlag(f, LOCAL_flagCount, false);
2046 }
2047 LOCAL_flagCount++;
2048 f++;
2049 }
2050 // fix readline gettong set so early
2051 if (GLOBAL_Stream[StdInStream].status & Readline_Stream_f) {
2052 setBooleanGlobalPrologFlag(READLINE_FLAG, true);
2053 }
2054 pop_text_stack(lvl);
2055 if (!bootstrap) {
2056 Yap_InitCPredBack("current_prolog_flag", 2, 1, current_prolog_flag,
2057 cont_yap_flag, 0);
2058 TR = tr0;
2059 Yap_InitCPredBack("prolog_flag", 3, 1, prolog_flag, cont_yap_flag,
2060 0);
2061 Yap_InitCPredBack("yap_flag", 3, 1, yap_flag, cont_yap_flag, 0);
2062 Yap_InitCPredBack("yap_flag", 2, 1, yap_flag2, cont_yap_flag, 0);
2063 Yap_InitCPredBack("prolog_flag", 2, 1, current_prolog_flag2,
2064 cont_current_prolog_flag, 0);
2065 Yap_InitCPredBack("current_prolog_flag", 2, 1, current_prolog_flag2,
2066 cont_current_prolog_flag, 0);
2067 Yap_InitCPred("set_prolog_flag", 2, set_prolog_flag, SyncPredFlag);
2068 Yap_InitCPred("$create_prolog_flag", 3, do_create_prolog_flag,
2069 SyncPredFlag);
2070 // Yap_InitCPredBack("yap_flag", 2, 1, yap_flag, cont_yap_flag, 0);
2071 Yap_InitCPredBack("prolog_flag_property", 2, 1, prolog_flag_property,
2072 cont_prolog_flag_property, 0);
2073 Yap_InitCPred("source", 0, source, SyncPredFlag);
2074 Yap_InitCPred("no_source", 0, no_source, SyncPredFlag);
2075 Yap_InitCPred("source_mode", 2, source_mode, SyncPredFlag);
2076 }
2077}
2078
2079/* Accessing and changing the flags for a predicate */
2080
2082
2083
global flags and their default values
Main definitions.
void * Malloc(size_t sz USES_REGS)
allocate a temporary text block
Definition: alloc.c:1759
void Yap_InitFlags(bool bootstrap)
Init System Prolog flags.
Definition: flags.c:2002
X_API bool Yap_create_prolog_flag(const char *name, bool writable, Term ttype, Term v)
Create a new global prolog flag.
Definition: flags.c:1968
@ argv
read-only atom, it describes the list with all arguments received by YAP at boot
Definition: YapGFlagInfo.h:89
@ source
If true maintain the source for all clauses.
Definition: YapGFlagInfo.h:601
@ executable
Read-only flag.
Definition: YapGFlagInfo.h:263
@ gc_margin
controls when to do garbage collection
Definition: YapGFlagInfo.h:297
@ compiling
Indicates YAP is running within the compiler.
Definition: YapLFlagInfo.h:73
prolog_flag/2 support, notice flag is initialized as text
Definition: YapFlags.h:173
Module property: low-level data used to manage modes.
Definition: Yatom.h:209
unsigned int flags
module's owner file
Definition: Yatom.h:219
Definition: tab.structs.h:22
Definition: YapFlags.h:152
a flag is represented as a Prolog term
Definition: YapFlags.h:189