YAP 7.1.0
yap-args.c
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 1985-1997 *
8 * *
9 **************************************************************************
10 * *
11 * File: Yap.C * Last
12 *Rev:
13 * Mods:
14 ** Comments: Yap's Main File: parse arguments *
15 * *
16 *************************************************************************/
17/* static char SccsId[] = "X 4.3.3"; */
18#include "Yap.h"
19#include "YapHeap.h"
20#include "YapInterface.h"
21#include "YapStreams.h"
22#include "iopreds.h"
23
24#if HAVE_UNISTD_H
25
26#include <unistd.h>
27
28#endif
29#if HAVE_STDINT_H
30
31#include <stdint.h>
32
33#endif
34
35#include <stdlib.h>
36
37#include <stddef.h>
38#ifdef _MSC_VER /* Microsoft's Visual C++ Compiler */
39#ifdef HAVE_UNISTD_H
40#undef HAVE_UNISTD_H
41#endif
42#endif
43
44#include <stdio.h>
45
46#if HAVE_STRING_H
47
48#include <string.h>
49
50#endif
51#if HAVE_ERRNO_H
52
53#include <errno.h>
54
55#endif
56#if HAVE_DIRECT_H
57#include <direct.h>
58#endif
59
60#if HAVE_LIBGEN_H
61#include <libgen.h>
62
63#endif
64
65X_API bool YAP_initialized = false;
66static int n_mdelays = 0;
67static YAP_delaymodule_t *m_delays;
68
69static void init_globals(YAP_init_args *yap_init) {
70 GLOBAL_FAST_BOOT_FLAG = yap_init->FastBoot;
71#if defined(YAPOR) || defined(TABLING)
72
73 Yap_init_root_frames();
74
75#endif /* YAPOR || TABLING */
76#ifdef YAPOR
77 Yap_init_yapor_workers();
78 if (
79#if YAPOR_THREADS
80 Yap_thread_self() != 0
81#else
82 worker_id != 0
83#endif
84 ) {
85#if defined(YAPOR_COPY) || defined(YAPOR_SBA)
86 /*
87 In the SBA we cannot just happily inherit registers
88 from the other workers
89 */
90 Yap_InitYaamRegs(worker_id, false);
91#endif /* YAPOR_COPY || YAPOR_SBA */
92#ifndef YAPOR_THREADS
93 Yap_InitPreAllocCodeSpace(0);
94#endif /* YAPOR_THREADS */
95 /* slaves, waiting for work */
96 CurrentModule = USER_MODULE;
97 P = GETWORK_FIRST_TIME;
98 Yap_exec_absmi(FALSE, YAP_EXEC_ABSMI);
99 Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil,
100 "abstract machine unexpected exit (YAP_Init)");
101 }
102#endif /* YAPOR */
103 RECOVER_MACHINE_REGS();
104 /* make sure we do this after restore */
105 if (yap_init->MaxStackSize) {
106 GLOBAL_AllowLocalExpansion = FALSE;
107 } else {
108 GLOBAL_AllowLocalExpansion = TRUE;
109 }
110 if (yap_init->MaxGlobalSize) {
111 GLOBAL_AllowGlobalExpansion = FALSE;
112 } else {
113 GLOBAL_AllowGlobalExpansion = TRUE;
114 }
115 if (yap_init->MaxTrailSize) {
116 GLOBAL_AllowTrailExpansion = FALSE;
117 } else {
118 GLOBAL_AllowTrailExpansion = TRUE;
119 }
120 if (yap_init->PrologRCFile) {
121 Yap_PutValue(AtomConsultOnBoot,
122 MkAtomTerm(Yap_LookupAtom(yap_init->PrologRCFile)));
123 /*
124 This must be done again after restore, as yap_flags
125 has been overwritten ....
126 */
127 setBooleanGlobalPrologFlag(HALT_AFTER_CONSULT_FLAG,
128 yap_init->HaltAfterBoot);
129 }
130 if (yap_init->PrologTopLevelGoal) {
131 Yap_PutValue(AtomTopLevelGoal,
132 MkAtomTerm(Yap_LookupAtom(yap_init->PrologTopLevelGoal)));
133 }
134 if (yap_init->PrologGoal) {
135 Yap_PutValue(AtomInitGoal,
136 MkAtomTerm(Yap_LookupAtom(yap_init->PrologGoal)));
137 }
138 if (yap_init->PrologAddPath) {
139 Yap_PutValue(AtomExtendFileSearchPath,
140 MkAtomTerm(Yap_LookupAtom(yap_init->PrologAddPath)));
141 }
142
143 if (yap_init->QuietMode) {
144 setBooleanLocalPrologFlag(VERBOSE_LOAD_FLAG, false);
145 }
146}
147
148
149const char *Yap_BINDIR, *Yap_ROOTDIR, *Yap_SHAREDIR, *Yap_LIBDIR, *Yap_DLLDIR,
150 *Yap_PLDIR, *Yap_BOOTSTRAP, *Yap_COMMONSDIR, *Yap_INPUT_STARTUP,
151 *Yap_OUTPUT_STARTUP, *Yap_SOURCEBOOT, *Yap_INCLUDEDIR, *Yap_PLBOOTDIR;
152
158static bool load_file(const char *b_file USES_REGS) {
159 Term t;
160 int c_stream, osno, oactive;
161
162 Functor functor_query = Yap_MkFunctor(Yap_LookupAtom("?-"), 1);
163 Functor functor_command1 = Yap_MkFunctor(Yap_LookupAtom(":-"), 1);
164 Functor functor_compile2 = Yap_MkFunctor(Yap_LookupAtom("c_compile"), 1);
165
166 /* consult in C */
167 int lvl = push_text_stack();
168
169 char *full = Malloc(MAX_PATH);
170 /* the consult mode does not matter here, really */
171 osno = Yap_CheckAlias(AtomLoopStream);
172 c_stream = YAP_InitConsult(YAP_BOOT_MODE, b_file, full, &oactive);
173 __android_log_print(
174 ANDROID_LOG_INFO, "YAPDroid", "done init_consult %s ",b_file);
175 if (c_stream < 0) {
176 fprintf(stderr, "[ FATAL ERROR: could not open file %s\n", b_file);
177 pop_text_stack(lvl);
178 exit(1);
179 }
180 if (!Yap_AddAlias(AtomLoopStream, c_stream)) {
181 pop_text_stack(lvl);
182 return false;
183 }
184 __android_log_print(
185 ANDROID_LOG_INFO, "YAPDroid", "do reset %s ",b_file);
186 t = 0;
187 while (t != TermEof) {
188 sigjmp_buf e;
189 LOCAL_RestartEnv = &e;
190
191 if (sigsetjmp(e,0) == 0) {
192 CACHE_REGS
193 YAP_Reset(YAP_FULL_RESET, false);
194 Yap_StartSlots();
195 Term vs[2];
196 RESET_VARIABLE(vs);
197 RESET_VARIABLE(vs+1);
198
199 t = YAP_ReadClauseFromStream(c_stream, vs[0], vs[1]);
200 // Yap_GetNèwSlot(t);
201 if (t == TermEof || t == TermNil) {
202 continue;
203 } else if (t == 0) {
204 fprintf(stderr, "%s:" Int_FORMAT " :0: error: SYNTAX ERROR\n",
205 b_file, GLOBAL_Stream[c_stream].linecount);
206 //
207 // {
208 // char buu[1024];
209 //1
210 // YAP_WriteBuffer(t, buu, 1023, 0);
211 // fprintf(stderr, "[ %s ]\n" , buu);
212 // }
213 continue;
214 } else if (IsVarTerm(t)) {
215 fprintf(stderr, "%s:" Int_FORMAT ":0: error: unbound or NULL parser output\n\n",
216 b_file,
217 GLOBAL_Stream[c_stream].linecount);
218 continue;
219 } else if (IsApplTerm(t) &&
220 (FunctorOfTerm(t) == functor_query ||
221 FunctorOfTerm(t) == functor_command1)) {
222 t = ArgOfTerm(1, t);
223 if (IsApplTerm(t) && FunctorOfTerm(t) == functor_compile2) {
224 load_file(RepAtom(AtomOfTerm(ArgOfTerm(1, t)))->StrOfAE);
225 continue;
226 } else {
227 YAP_RunGoalOnce(t);
228 }
229
230 } else {
231 YAP_CompileClause(t);
232 }
233 } else {
234 }
236 if ((errd = Yap_GetException()) &&
237 (errd->errorNo != YAP_NO_ERROR)) {
238 fprintf(stderr, "%s:" Int_FORMAT ":0: error: %s/%s %s\n\n", b_file, errd->errorLine, errd->errorAsText, errd->classAsText, errd->errorMsg);
239 }
240 }
241 BACKUP_MACHINE_REGS();
242 YAP_EndConsult(c_stream, &osno, full);
243 pop_text_stack(lvl);
244 return t == TermEof;
245}
246
247static const char * EOLIST ="EOLINE";
248static bool is_install;
249
250static bool is_dir( const char *path, const void *info) {
251 if (is_install)
252 return true;
253
254 if (Yap_isDirectory( path ))
255 return true;
256 char s[MAX_PATH + 1];
257 Int i = strlen(path);
258 strncpy(s, path, MAX_PATH);
259 while (--i) {
260 if (Yap_dir_separator((int)path[i]))
261 break;
262 }
263 if (i == 0) {
264 s[0] = '.';
265 i = 1;
266 }
267 s[i] = '\0';
268 if (info == NULL)
269 return true;
270 return
271 strcmp(info,s) == 0 ||
272 Yap_isDirectory( s );
273}
274
275static bool is_file( const char *path, const void *info) {
276 if (is_install)
277 return true;
278 return Yap_Exists( path );
279}
280
281static bool is_wfile( const char *path, const void *info) {
282
283 return true;
284}
285
286typedef bool testf(const char *s, const void *info);
287
288
291static const char *sel(
292 testf test, const void *info, const char *s1, ...) {
293 const char *fmt = s1;
294 va_list ap;
295 char *buf = malloc(FILENAME_MAX + 1);
296
297 va_start(ap, s1);
298 while (fmt != EOLIST) {
299 if (fmt == NULL || fmt[0]=='\0') {
300 fmt = va_arg(ap, const char *);
301 continue;
302 }
303 strncpy(buf, fmt, FILENAME_MAX); // Yap_AbsoluteFile(fmt,true), FILENAME_MAX);
304 if (test(buf,info)) {
305 buf = realloc(buf, strlen(buf) + 1);
306 va_end(ap);
307 return buf;
308 }
309 fmt = va_arg(ap, const char *);
310 }
311
312 va_end(ap);
313 free(buf);
314 return NULL;
315}
316
317
318static const char *join(const char *s0, const char *s1) {
319 CACHE_REGS
320
321 if (!s0 || s0[0] == '\0') {
322 if (s1 && s1[0])
323 return s1;
324 else
325 return NULL;
326 }
327 if (!s1 || s1[0] == '\0')
328 return s0;
329 // int lvl = push_text_stack();
330 char *buf = malloc(strlen(s0)+strlen(s1) + 2);
331 strcpy(buf, s0);
332 if (Yap_dir_separator(s0[strlen(s0)-1])) {
333 if (Yap_dir_separator(s1[0])) {
334 s1 += 1;
335 }
336 } else {
337 if (!Yap_dir_separator(s1[0]-1)) {
338 strcat(buf, "/");
339 }
340 }
341 strcat(buf, s1);
342 return buf;
343}
344
345static void Yap_set_locations(YAP_init_args *iap) {
346 is_install= iap->install;
352 // --_not useful in Android, WIN32;
355 Yap_ROOTDIR = sel( is_dir, NULL,
356 iap->ROOTDIR,
357 getenv("YAPROOTDIR"),
358 join(getenv("DESTDIR"), YAP_ROOTDIR),
359
360#if __ANDROID__
361 "/",
362#else
363 join(getenv("DESTDIR"), YAP_ROOTDIR),
364 join(getenv("DESTDIR"), join(getenv("ḦOME"),".local")),
365 join(getenv("DESTDIR"), "/usr/local"),
366 join(getenv("DESTDIR"), "/usr"),
367 join(getenv("DESTDIR"), "/opt"),
368#endif
369 EOLIST
370 );
371 __android_log_print(
372 ANDROID_LOG_INFO,"YAPDroid", "Yap_ROOTDIR %s", Yap_ROOTDIR);
373
375 Yap_BINDIR = sel( is_dir, Yap_ROOTDIR, iap->BINDIR,
376 getenv("YAPBINDIR"),
377#if !defined(__ANDROID__)
378 join(getenv("DESTDIR"), YAP_BINDIR),
379#endif
380 join(Yap_ROOTDIR, "bin"),
381 EOLIST);
382
384 Yap_LIBDIR = sel( is_dir, Yap_ROOTDIR, iap->LIBDIR,
385#if !defined(__ANDROID__)
386 join(getenv("DESTDIR"), YAP_LIBDIR),
387#endif
388 join(Yap_ROOTDIR, "lib"),
389 EOLIST);
390
392 Yap_DLLDIR = sel(is_dir, Yap_LIBDIR, iap->DLLDIR,
393 getenv("YAPLIBDIR"),
394 join(getenv("DESTDIR"), YAP_DLLDIR),
395 join(Yap_DLLDIR, "Yap"),
396 EOLIST);
397
399 Yap_INCLUDEDIR = sel(is_dir, Yap_ROOTDIR, iap->INCLUDEDIR,
400#if !defined(__ANDROID__)
401 join(getenv("DESTDIR"), YAP_INCLUDEDIR),
402#endif
403 join(Yap_ROOTDIR, "include"),
404 EOLIST);
405
406
408 Yap_SHAREDIR = sel( is_dir, Yap_ROOTDIR, iap->SHAREDIR,
409 getenv("YAPSHAREDIR"),
410#if __ANDROID__
411 "/data/data/pt.up.yap/files",
412 "/assets",
413#endif
414 join(getenv("DESTDIR"), YAP_SHAREDIR),
415 join(Yap_ROOTDIR, "share"),
416 join(Yap_ROOTDIR, "files"),
417 EOLIST);
418 __android_log_print(
419 ANDROID_LOG_INFO,"YAPDroid", "Yap_SHAREDIR %s", Yap_SHAREDIR);
420
421
422
424 Yap_PLDIR = sel( is_dir, Yap_SHAREDIR, iap->PLDIR,
425 join(getenv("DESTDIR"), join(Yap_SHAREDIR, "Yap")),
426 EOLIST);
427
428 __android_log_print(
429 ANDROID_LOG_INFO, "YAPDroid","Yap_PLDIR %s", Yap_PLDIR);
430
432 Yap_COMMONSDIR = sel(is_dir, Yap_SHAREDIR, iap->COMMONSDIR,
433 join(getenv("DESTDIR"), join(Yap_SHAREDIR, "PrologCommons")),
434 EOLIST);
436 Yap_SOURCEBOOT = sel( is_file, Yap_AbsoluteFile("pl",false), iap->SOURCEBOOT,
437 YAP_SOURCEBOOT,
438 "boot.yap",
439 "../pl/boot.yap",
440 EOLIST);
441 __android_log_print(
442 ANDROID_LOG_INFO, "YAPDroid","Yap_SOURCEBOOT %s", Yap_SOURCEBOOT);
443
444 Yap_PLBOOTDIR = sel( is_dir, Yap_PLDIR, iap->BOOTDIR,
445 join(getenv("DESTDIR"),join(Yap_PLDIR, "pl")),
446 EOLIST);
447 __android_log_print(
448 ANDROID_LOG_INFO, "YAPDroid","Yap_BOOTSTRAP %s", Yap_BOOTSTRAP);
450 Yap_BOOTSTRAP = sel( is_file, Yap_PLBOOTDIR, iap->BOOTSTRAP,
451 join(getenv("DESTDIR"),YAP_BOOTSTRAP),
452 join(getenv("DESTDIR"),join(Yap_PLBOOTDIR, "boot.yap")),
453 EOLIST);
454 __android_log_print(
455 ANDROID_LOG_INFO,"YAPDroid", "Yap_BOOTSTRAP %s", Yap_PLBOOTDIR);
457 Yap_OUTPUT_STARTUP =
458 sel( is_wfile, ".", iap->OUTPUT_STARTUP,
459 YAP_OUTPUT_STARTUP,
460 join(getenv("DESTDIR"), join(Yap_DLLDIR, "startup.yss")),
461 join(getenv("DESTDIR"), join(Yap_DLLDIR,iap->OUTPUT_STARTUP)),
462 "startup.yss",
463 EOLIST);
464
465 Yap_INPUT_STARTUP =
466 sel( is_file, Yap_DLLDIR, iap->INPUT_STARTUP,
467 "startup.yss",
468 join(getenv("DESTDIR"), join(Yap_DLLDIR, "startup.yss")),
469#if !defined(__ANDROID__)
470 join(getenv("DESTDIR"), YAP_INPUT_STARTUP),
471#endif
472 "/usr/local/lib/Yap/startup.yss",
473 "/usr/lib/Yap/startup.yss",
474 EOLIST);
475
476 if (Yap_ROOTDIR)
477 setAtomicGlobalPrologFlag(HOME_FLAG,
478 MkAtomTerm(Yap_LookupAtom(Yap_ROOTDIR)));
479 if (Yap_PLDIR)
480 setAtomicGlobalPrologFlag(PROLOG_LIBRARY_DIRECTORY_FLAG,
481 MkAtomTerm(Yap_LookupAtom(Yap_PLDIR)));
482 if (Yap_DLLDIR)
483 setAtomicGlobalPrologFlag(PROLOG_FOREIGN_DIRECTORY_FLAG,
484 MkAtomTerm(Yap_LookupAtom(Yap_DLLDIR)));
485}
486
487static void print_usage(void) {
488 fprintf(stderr, "\n[ Valid switches for command line arguments: ]\n");
489 fprintf(stderr, " -? Shows this screen\n");
490 fprintf(stderr, " -B Used during compilation: boot from ../pl/boot.yap and generate a saved state. \n");
491 fprintf(stderr, " -b Boot file \n");
492 fprintf(stderr, " -dump-runtime-variables\n");
493 fprintf(stderr, " -f initialization file or \"none\"\n");
494 fprintf(stderr, " -g Run Goal Before Top-Level \n");
495 fprintf(stderr, " -z Run Goal Before Top-Level \n");
496 fprintf(stderr, " -q start with informational messages off\n");
497 fprintf(stderr, " -l load Prolog file\n");
498 fprintf(stderr, " -L run Prolog file and exit\n");
499 fprintf(stderr, " -p extra path for file-search-path\n");
500 fprintf(stderr, " -hSize Heap area in Kbytes (default: %d, minimum: %d)\n",
501 DefHeapSpace, MinHeapSpace);
502 fprintf(stderr,
503 " -sSize Stack area in Kbytes (default: %d, minimum: %d)\n",
504 DefStackSpace, MinStackSpace);
505 fprintf(stderr,
506 " -tSize Trail area in Kbytes (default: %d, minimum: %d)\n",
507 DefTrailSpace, MinTrailSpace);
508 fprintf(stderr, " -GSize Max Area for Global Stack\n");
509 fprintf(stderr,
510 " -LSize Max Area for Local Stack (number must follow L)\n");
511 fprintf(stderr, " -TSize Max Area for Trail (number must follow T)\n");
512 fprintf(stderr, " -nosignals disable signal handling from Prolog\n");
513 fprintf(stderr, "\n[Execution Modes]\n");
514 fprintf(stderr, " -J0 Interpreted mode (default)\n");
515 fprintf(stderr, " -J1 Mixed mode only for user predicates\n");
516 fprintf(stderr, " -J2 Mixed mode for all predicates\n");
517 fprintf(stderr, " -J3 Compile all user predicates\n");
518 fprintf(stderr, " -J4 Compile all predicates\n");
519
520#ifdef TABLING
521 fprintf(stderr,
522 " -ts Maximum table space area in Mbytes (default: unlimited)\n");
523#endif /* TABLING */
524#if defined(YAPOR_COPY) || defined(YAPOR_COW) || defined(YAPOR_SBA) || \
525 defined(YAPOR_THREADS)
526 fprintf(stderr, " -w Number of workers (default: %d)\n",
527 DEFAULT_NUMBERWORKERS);
528 fprintf(stderr,
529 " -sl Loop scheduler executions before look for hiden "
530 "shared work (default: %d)\n",
531 DEFAULT_SCHEDULERLOOP);
532 fprintf(stderr, " -d Value of delayed release of load (default: %d)\n",
533 DEFAULT_DELAYEDRELEASELOAD);
534#endif /* YAPOR_COPY || YAPOR_COW || YAPOR_SBA || YAPOR_THREADS */
535 /* nf: Preprocessor */
536 /* fprintf(stderr," -DVar=Name Persistent definition\n"); */
537 fprintf(stderr, "\n");
538}
539
540static int myisblank(int c) {
541 switch (c) {
542 case ' ':
543 case '\t':
544 case '\n':
545 case '\r':
546 return TRUE;
547 default:
548 return FALSE;
549 }
550}
551
552static char *add_end_dot(char arg[]) {
553 int sz = strlen(arg), i;
554 i = sz;
555 while (i && myisblank(arg[--i]))
556 ;
557 if (i && arg[i] != ',') {
558 char *p = (char *)malloc(sz + 2);
559 if (!p)
560 return NULL;
561 strncpy(p, arg, sz);
562 p[sz] = '.';
563 p[sz + 1] = '\0';
564 return p;
565 }
566 return arg;
567}
568
569static int dump_runtime_variables(void) {
570 fprintf(stdout, "CC=\"%s\"\n", C_CC);
571 fprintf(stdout, "YAP_ROOTDIR=\"%s\"\n", YAP_ROOTDIR);
572 fprintf(stdout, "YAP_LIBS=\"%s\"\n", C_LIBS);
573 fprintf(stdout, "YAP_SHLIB_SUFFIX=\"%s\"\n", SO_EXT);
574 fprintf(stdout, "YAP_VERSION=%s\n", YAP_NUMERIC_VERSION);
575 exit(0);
576 return 1;
577}
578
579X_API YAP_file_type_t Yap_InitDefaults(void *x, char *saved_state, int argc,
580 char *argv[]) {
581
582 if (!LOCAL_TextBuffer)
583 LOCAL_TextBuffer = Yap_InitTextAllocator();
584 YAP_init_args *iap = x;
585 memset(iap, 0, sizeof(YAP_init_args));
586 iap->Argc = argc;
587 iap->Argv = argv;
588#if __ANDROID__
589 iap->boot_file_type = YAP_PL;
590 iap->INPUT_STARTUP = NULL;
591 iap->assetManager = NULL;
592 return YAP_PL;
593#else
594 iap->boot_file_type = YAP_QLY;
595 iap->INPUT_STARTUP = saved_state;
596 return YAP_QLY;
597#endif
598}
599
607X_API YAP_file_type_t YAP_parse_yap_arguments(int argc, char *argv[], YAP_init_args *iap) {
608 char *p;
609 size_t *ssize;
610
611 Yap_InitDefaults(iap, NULL, argc, argv);
612 while (--argc > 0) {
613 p = *++argv;
614 if (*p == '-')
615 switch (*++p) {
616 case 'b':
617 iap->boot_file_type = YAP_PL;
618 if (p[1])
619 iap->BOOTSTRAP = p + 1;
620 else if (argv[1] && *argv[1] != '-') {
621 iap->BOOTSTRAP = *++argv;
622 argc--;
623 }
624 break;
625 case 'B':
626 iap->boot_file_type = YAP_SOURCE_PL;
627 if (p[1])
628 iap->SOURCEBOOT = p + 1;
629 else if (argv[1] && *argv[1] != '-') {
630 iap->SOURCEBOOT = *++argv;
631 argc--;
632 }
633 iap->install = true;
634 break;
635 case '?':
636 print_usage();
637 exit(EXIT_SUCCESS);
638 case 'q':
639 iap->QuietMode = TRUE;
640 break;
641#if defined(YAPOR_COPY) || defined(YAPOR_COW) || defined(YAPOR_SBA) || \
642 defined(YAPOR_THREADS)
643 case 'w':
644 ssize = &(iap->NumberWorkers);
645 goto GetSize;
646 case 'd':
647 if (!strcmp("dump-runtime-variables", p))
648 return dump_runtime_variables();
649 ssize = &(iap->DelayedReleaseLoad);
650 goto GetSize;
651#else
652 case 'd':
653 if (!strcmp("dump-runtime-variables", p))
654 return dump_runtime_variables();
655#endif /* YAPOR_COPY || YAPOR_COW || YAPOR_SBA || YAPOR_THREADS */
656 case 'F':
657 /* just ignore for now */
658 argc--;
659 argv++;
660 break;
661 case 'f':
662 iap->FastBoot = TRUE;
663 if (argc > 1 && argv[1][0] != '-') {
664 argc--;
665 argv++;
666 if (strcmp(*argv, "none")) {
667 iap->PrologRCFile = *argv;
668 }
669 break;
670 }
671 break;
672 // execution mode
673 case 'J':
674 switch (p[1]) {
675 case '0':
676 iap->ExecutionMode = YAPC_INTERPRETED;
677 break;
678 case '1':
679 iap->ExecutionMode = YAPC_MIXED_MODE_USER;
680 break;
681 case '2':
682 iap->ExecutionMode = YAPC_MIXED_MODE_ALL;
683 break;
684 case '3':
685 iap->ExecutionMode = YAPC_COMPILE_USER;
686 break;
687 case '4':
688 iap->ExecutionMode = YAPC_COMPILE_ALL;
689 break;
690 default:
691 fprintf(stderr, "[ YAP unrecoverable error: unknown switch -%c%c ]\n",
692 *p, p[1]);
693 exit(EXIT_FAILURE);
694 }
695 p++;
696 break;
697 case 'G':
698 ssize = &(iap->MaxGlobalSize);
699 goto GetSize;
700 break;
701 case 's':
702 case 'S':
703 ssize = &(iap->StackSize);
704#if defined(YAPOR_COPY) || defined(YAPOR_COW) || defined(YAPOR_SBA) || \
705 defined(YAPOR_THREADS)
706 if (p[1] == 'l') {
707 p++;
708 ssize = &(iap->SchedulerLoop);
709 }
710#endif /* YAPOR_COPY || YAPOR_COW || YAPOR_SBA || YAPOR_THREADS */
711 goto GetSize;
712 case 'a':
713 case 'A':
714 ssize = &(iap->AttsSize);
715 goto GetSize;
716 case 'T':
717 ssize = &(iap->MaxTrailSize);
718 goto get_trail_size;
719 case 't':
720 ssize = &(iap->TrailSize);
721#ifdef TABLING
722 if (p[1] == 's') {
723 p++;
724 ssize = &(iap->MaxTableSpaceSize);
725 }
726#endif /* TABLING */
727 get_trail_size:
728 if (*++p == '\0') {
729 if (argc > 1)
730 --argc, p = *++argv;
731 else {
732 fprintf(stderr,
733 "[ YAP unrecoverable error: missing size in flag %s ]",
734 argv[0]);
735 print_usage();
736 exit(EXIT_FAILURE);
737 }
738 }
739 {
740 unsigned long int i = 0, ch;
741 while ((ch = *p++) >= '0' && ch <= '9')
742 i = i * 10 + ch - '0';
743 switch (ch) {
744 case 'M':
745 case 'm':
746 i *= 1024;
747 ch = *p++;
748 break;
749 case 'g':
750 i *= 1024 * 1024;
751 ch = *p++;
752 break;
753 case 'k':
754 case 'K':
755 ch = *p++;
756 break;
757 }
758 if (ch) {
759 iap->PrologTopLevelGoal = add_end_dot(*argv);
760 } else {
761 *ssize = i;
762 }
763 }
764 break;
765 case 'h':
766 case 'H':
767 ssize = &(iap->HeapSize);
768 GetSize:
769 if (*++p == '\0') {
770 if (argc > 1)
771 --argc, p = *++argv;
772 else {
773 fprintf(stderr,
774 "[ YAP unrecoverable error: missing size in flag %s ]",
775 argv[0]);
776 print_usage();
777 exit(EXIT_FAILURE);
778 }
779 }
780 {
781 unsigned long int i = 0, ch;
782 while ((ch = *p++) >= '0' && ch <= '9')
783 i = i * 10 + ch - '0';
784 switch (ch) {
785 case 'M':
786 case 'm':
787 i *= 1024;
788 ch = *p++;
789 break;
790 case 'g':
791 case 'G':
792 i *= 1024 * 1024;
793 ch = *p++;
794 break;
795 case 'k':
796 case 'K':
797 ch = *p++;
798 break;
799 }
800 if (ch) {
801 fprintf(
802 stderr,
803 "[ YAP unrecoverable error: illegal size specification %s ]",
804 argv[-1]);
805 Yap_exit(1);
806 }
807 *ssize = i;
808 }
809 break;
810#ifdef DEBUG
811 case 'P':
812 if (p[1] != '\0') {
813 while (p[1] != '\0') {
814 int ch = p[1];
815 if (ch >= 'A' && ch <= 'Z')
816 ch += ('a' - 'A');
817 if (ch >= 'a' && ch <= 'z')
818 GLOBAL_Option[ch - 96] = 1;
819 p++;
820 }
821 } else {
822 YAP_SetOutputMessage();
823 }
824 break;
825#endif
826 case 'L':
827 if (p[1] && p[1] >= '0' &&
828 p[1] <= '9') /* hack to emulate SWI's L local option */
829 {
830 ssize = &(iap->MaxStackSize);
831 goto GetSize;
832 }
833 iap->QuietMode = TRUE;
834 iap->HaltAfterBoot = true;
835 case 'l':
836 p++;
837 iap->QuietMode = TRUE;
838 if (!*++argv) {
839 fprintf(stderr,
840 "%% YAP unrecoverable error: missing load file name\n");
841 exit(1);
842 } else if (!strcmp("--", *argv)) {
843 /* shell script, the next entry should be the file itself */
844 iap->PrologRCFile = argv[1];
845 argc = 1;
846 break;
847 } else {
848 iap->PrologRCFile = *argv;
849 argc--;
850 }
851 if (*p) {
852 /* we have something, usually, of the form:
853 -L --
854 FileName
855 ExtraArgs
856 */
857 /* being called from a script */
858 while (*p && (*p == ' ' || *p == '\t'))
859 p++;
860 if (p[0] == '-' && p[1] == '-') {
861 /* ignore what is next */
862 argc = 1;
863 }
864 }
865 break;
866 /* run goal before top-level */
867 case 'g':
868 if ((*argv)[0] == '\0')
869 iap->PrologGoal = *argv;
870 else {
871 argc--;
872 if (argc == 0) {
873 fprintf(stderr, " [ YAP unrecoverable error: missing "
874 "initialization goal for option 'g' ]\n");
875 exit(EXIT_FAILURE);
876 }
877 argv++;
878 iap->PrologGoal = *argv;
879 }
880 break;
881 /* run goal as top-level */
882 case 'z':
883 if ((*argv)[0] == '\0')
884 iap->PrologTopLevelGoal = *argv;
885 else {
886 argc--;
887 if (argc == 0) {
888 fprintf(stderr, " [ YAP unrecoverable error: missing goal for "
889 "option 'z' ]\n");
890 exit(EXIT_FAILURE);
891 }
892 argv++;
893 iap->PrologTopLevelGoal = add_end_dot(*argv);
894 }
895 iap->HaltAfterBoot = true;
896 break;
897 case 'n':
898 if (!strcmp("nosignals", p)) {
899 iap->PrologCannotHandleInterrupts = true;
900 break;
901 }
902 break;
903 case '-':
904 if (!strcmp("-nosignals", p)) {
905 iap->PrologCannotHandleInterrupts = true;
906 break;
907 } else if (!strncmp("-output-saved-state=", p,
908 strlen("-output-saved-state="))) {
909 iap->OUTPUT_STARTUP = p + strlen("-output-saved-state=");
910 } else if (!strncmp("-home=", p, strlen("-home="))) {
911 iap->ROOTDIR = p + strlen("-home=");
912 } else if (!strncmp("-system-library-directory=", p,
913 strlen("-system-library-directory="))) {
914 iap->LIBDIR = p + strlen("-system-library-directory=");
915 } else if (!strncmp("-system-shared-directory=", p,
916 strlen("-system-shared-directory="))) {
917 iap->SHAREDIR = p + strlen("-system-shared-directory=");
918 } else if (!strncmp("-prolog-library-directory=", p,
919 strlen("-prolog-library-directory="))) {
920 iap->PLDIR = p + strlen("-prolog-library-directory=");
921 } else if (!strncmp("-dll-library-directory=", p,
922 strlen("-dll-library-directory="))) {
923 iap->DLLDIR = p + strlen("-dll-library-directory=");
924 } else if (!strncmp("-home=", p, strlen("-home="))) {
925 iap->ROOTDIR = p + strlen("-home=");
926 } else if (!strncmp("-cwd=", p, strlen("-cwd="))) {
927 if (!Yap_ChDir(p + strlen("-cwd="))) {
928 fprintf(stderr, " [ YAP unrecoverable error in setting cwd: %s ]\n",
929 strerror(errno));
930 }
931 } else if (!strncmp("-stack=", p, strlen("-stack="))) {
932 ssize = &(iap->StackSize);
933 p += strlen("-stack=");
934 goto GetSize;
935 } else if (!strncmp("-trail=", p, strlen("-trail="))) {
936 ssize = &(iap->TrailSize);
937 p += strlen("-trail=");
938 goto GetSize;
939 } else if (!strncmp("-heap=", p, strlen("-heap="))) {
940 ssize = &(iap->HeapSize);
941 p += strlen("-heap=");
942 goto GetSize;
943 } else if (!strncmp("-max-stack=", p, strlen("-max-stack="))) {
944 ssize = &(iap->MaxStackSize);
945 p += strlen("-max-stack=");
946 goto GetSize;
947 } else if (!strncmp("-max-trail=", p, strlen("-max-trail="))) {
948 ssize = &(iap->MaxTrailSize);
949 p += strlen("-max-trail=");
950 goto GetSize;
951 } else if (!strncmp("-max-heap=", p, strlen("-max-heap="))) {
952 ssize = &(iap->MaxHeapSize);
953 p += strlen("-max-heap=");
954 goto GetSize;
955 } else if (!strncmp("-goal=", p, strlen("-goal="))) {
956 iap->PrologGoal = p + strlen("-goal=");
957 } else if (!strncmp("-top-level=", p, strlen("-top-level="))) {
958 iap->PrologTopLevelGoal = p + strlen("-top-level=");
959 } else if (!strncmp("-table=", p, strlen("-table="))) {
960 ssize = &(iap->MaxTableSpaceSize);
961 p += strlen("-table=");
962 goto GetSize;
963 } else if (!strncmp("-", p, strlen("-="))) {
964 ssize = &(iap->MaxTableSpaceSize);
965 p += strlen("-table=");
966 /* skip remaining arguments */
967 argc = 1;
968 }
969 break;
970 case 'p':
971 if ((*argv)[0] == '\0')
972 iap->PrologAddPath = *argv;
973 else {
974 argc--;
975 if (argc == 0) {
976 fprintf(stderr, " [ YAP unrecoverable error: missing paths for "
977 "option 'p' ]\n");
978 exit(EXIT_FAILURE);
979 }
980 argv++;
981 iap->PrologAddPath = *argv;
982 }
983 break;
984 /* nf: Begin preprocessor code */
985 case 'D': {
986 char *var, *value;
987 ++p;
988 var = p;
989 if (var == NULL || *var == '\0')
990 break;
991 while (*p != '=' && *p != '\0')
992 ++p;
993 if (*p == '\0')
994 break;
995 *p = '\0';
996 ++p;
997 value = p;
998 if (*value == '\0')
999 break;
1000 if (iap->def_c == YAP_MAX_YPP_DEFS)
1001 break;
1002 iap->def_var[iap->def_c] = var;
1003 iap->def_value[iap->def_c] = value;
1004 ++(iap->def_c);
1005 break;
1006 }
1007 /* End preprocessor code */
1008 default: {
1009 fprintf(stderr, "[ YAP unrecoverable error: unknown switch -%c ]\n",
1010 *p);
1011 print_usage();
1012 exit(EXIT_FAILURE);
1013 }
1014 }
1015 else {
1016 iap->INPUT_STARTUP = p;
1017 }
1018 }
1019 return iap->boot_file_type;
1020}
1021
1030X_API bool YAP_DelayInit(YAP_ModInit_t f, const char s[]) {
1031 if (m_delays) {
1032 m_delays = realloc(m_delays, (n_mdelays + 1) * sizeof(YAP_delaymodule_t));
1033 } else {
1034 m_delays = malloc(sizeof(YAP_delaymodule_t));
1035 }
1036 m_delays[n_mdelays].f = f;
1037 m_delays[n_mdelays].s = s;
1038 n_mdelays++;
1039 return true;
1040}
1041
1042bool Yap_LateInit(const char s[]) {
1043 int i;
1044 for (i = 0; i < n_mdelays; i++) {
1045 if (!strcmp(m_delays[i].s, s)) {
1046 m_delays[i].f();
1047 return true;
1048 }
1049 }
1050 return false;
1051}
1052
1053struct ssz_t {
1054 size_t Heap, Stack, Trail;
1055};
1056
1057extern bool Yap_Embedded;
1058
1059static void init_hw(YAP_init_args *yap_init, struct ssz_t *spt) {
1060 Yap_page_size = Yap_InitPageSize(); /* init memory page size, required by
1061 later functions */
1062#if defined(YAPOR_COPY) || defined(YAPOR_COW) || defined(YAPOR_SBA)
1063 Yap_init_yapor_global_local_memory();
1064#endif /* YAPOR_COPY || YAPOR_COW || YAPOR_SBA */
1065 if (yap_init->Embedded) {
1066 yap_init->install = false;
1067 GLOBAL_PrologShouldHandleInterrupts =
1068 yap_init->PrologCannotHandleInterrupts = true;
1069 Yap_Embedded = true;
1070 } else {
1071 GLOBAL_PrologShouldHandleInterrupts =
1072 !yap_init->PrologCannotHandleInterrupts;
1073
1074 GLOBAL_PL_Argv = yap_init->Argv;
1075
1076 }
1077 Yap_InitSysbits(0); /* init signal handling and time, required by later
1078 functions */
1079 GLOBAL_argv = yap_init->Argv;
1080 GLOBAL_argc = yap_init->Argc;
1081
1082
1083 if (yap_init->TrailSize == 0) {
1084 if (spt->Trail == 0)
1085 spt->Trail = DefTrailSpace;
1086 } else {
1087 spt->Trail = yap_init->TrailSize;
1088 }
1089 // Atts = yap_init->AttsSize;
1090 if (yap_init->StackSize == 0) {
1091 spt->Stack = DefStackSpace;
1092 } else {
1093 spt->Stack = yap_init->StackSize;
1094 }
1095#ifndef USE_SYSTEM_MALLOC
1096 if (yap_init->HeapSize == 0) {
1097 if (spt->Heap == 0)
1098 spt->Heap = DefHeapSpace;
1099 } else {
1100 spt->Heap = yap_init->HeapSize;
1101 }
1102#endif
1103}
1104
1105static void end_init(YAP_init_args *iap) {
1106 YAP_initialized = true;
1107 if (iap->HaltAfterBoot)
1108 Yap_exit(0);
1109 LOCAL_PrologMode &= ~BootMode;
1110 CurrentModule = USER_MODULE;
1111 LOCAL_SourceModule = USER_MODULE;
1112}
1113
1114static void start_modules(void) {
1115 Term cm = CurrentModule;
1116 size_t i;
1117 for (i = 0; i < n_mdelays; i++) {
1118 CurrentModule = MkAtomTerm(YAP_LookupAtom(m_delays[i].s));
1119 m_delays[i].f();
1120 }
1121 CurrentModule = cm;
1122}
1123
1124/* this routine is supposed to be called from an external program
1125 that wants to control Yap */
1126
1127X_API void YAP_Init(YAP_init_args *yap_init) {
1128
1129#if __ANDROID__
1130
1131 // if (yap_init->assetManager)
1132//Yap_InitAssetManager();
1133#endif
1134GLOBAL_VFS = NULL;
1135 bool try_restore = yap_init->boot_file_type == YAP_QLY;
1136 bool do_bootstrap = yap_init->boot_file_type == YAP_PL ||
1137 yap_init->boot_file_type == YAP_SOURCE_PL;
1138 struct ssz_t minfo;
1139 __android_log_print(
1140 ANDROID_LOG_INFO, "YAPDroid", "start init ");
1141 if (YAP_initialized)
1142 /* ignore repeated calls to YAP_Init */
1143 return;
1144 if (!LOCAL_TextBuffer)
1145 LOCAL_TextBuffer = Yap_InitTextAllocator();
1146
1147 Yap_Embedded = yap_init->Embedded;
1148
1149 minfo.Trail = 0, minfo.Stack = 0, minfo.Trail = 0;
1150 init_hw(yap_init, &minfo);
1151 Yap_InitWorkspace(yap_init, minfo.Heap, minfo.Stack, minfo.Trail, 0,
1152 yap_init->MaxTableSpaceSize, yap_init->NumberWorkers,
1153 yap_init->SchedulerLoop, yap_init->DelayedReleaseLoad);
1154 //
1155
1156 CACHE_REGS
1157 CurrentModule = PROLOG_MODULE;
1158
1159 if (yap_init->QuietMode) {
1160 setBooleanLocalPrologFlag(VERBOSE_LOAD_FLAG,
1161 false);
1162 }
1163 if (yap_init->PrologRCFile != NULL) {
1164 /*
1165 This must be done before restore, otherwise
1166 restore will print out messages ....
1167 */
1168 setBooleanGlobalPrologFlag(HALT_AFTER_CONSULT_FLAG,
1169 yap_init->HaltAfterBoot);
1170 }
1171 /* tell the system who should cope with interrupts */
1172 Yap_ExecutionMode = yap_init->ExecutionMode;
1173 Yap_set_locations(yap_init);
1174
1175 if (Yap_INPUT_STARTUP==NULL)
1176 try_restore = false;
1177 if (do_bootstrap || !try_restore ||
1178 !Yap_SavedInfo(Yap_INPUT_STARTUP, &minfo.Trail, &minfo.Stack,
1179 &minfo.Heap)) {
1180 init_globals(yap_init);
1181
1182 start_modules();
1183 TermEof = MkAtomTerm(Yap_LookupAtom("end_of_file"));
1184 LOCAL_consult_level = -1;
1185 __android_log_print(
1186 ANDROID_LOG_INFO, "YAPDroid", "init %s ", Yap_BOOTSTRAP);
1187 if (yap_init->install) {
1188 load_file(Yap_SOURCEBOOT PASS_REGS);
1189 setAtomicGlobalPrologFlag(RESOURCE_DATABASE_FLAG,
1190 MkAtomTerm(Yap_LookupAtom(Yap_SOURCEBOOT)));
1191 }
1192 else {
1193 load_file(Yap_BOOTSTRAP PASS_REGS);
1194 setAtomicGlobalPrologFlag(RESOURCE_DATABASE_FLAG,
1195 MkAtomTerm(Yap_LookupAtom(Yap_BOOTSTRAP)));
1196 }
1197
1198 CurrentModule = LOCAL_SourceModule = TermUser;
1199 setBooleanGlobalPrologFlag(SAVED_PROGRAM_FLAG, false);
1200 } else {
1201 if (yap_init->QuietMode) {
1202 setBooleanLocalPrologFlag(VERBOSE_LOAD_FLAG, false);
1203 setBooleanLocalPrologFlag(COMPILING_FLAG, true);
1204 }
1205 __android_log_print(
1206 ANDROID_LOG_INFO, "YAPDroid", "restore %s ",Yap_INPUT_STARTUP );
1207 Yap_Restore(Yap_INPUT_STARTUP);
1208 CurrentModule = LOCAL_SourceModule = TermUser;
1209 init_globals(yap_init);
1210
1211 start_modules();
1212 if (yap_init->install && Yap_OUTPUT_STARTUP) {
1213 setAtomicGlobalPrologFlag(RESOURCE_DATABASE_FLAG,
1214 MkAtomTerm(Yap_LookupAtom(Yap_INPUT_STARTUP)));
1215 setBooleanGlobalPrologFlag(SAVED_PROGRAM_FLAG, true);
1216 }
1217 LOCAL_consult_level = 0;
1218 }
1219 YAP_RunGoalOnce(TermInitProlog);
1220 setBooleanLocalPrologFlag(COMPILING_FLAG, false);
1221 setBooleanLocalPrologFlag(VERBOSE_LOAD_FLAG, true);
1222 if (yap_init->install && Yap_OUTPUT_STARTUP) {
1223 Term t = MkAtomTerm(Yap_LookupAtom(Yap_OUTPUT_STARTUP));
1224 Term g = Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("qsave_program"), 1),
1225 1, &t);
1226 YAP_RunGoalOnce(g);
1227 }
1228
1229 end_init(yap_init);
1230}
1231
1232#if (DefTrailSpace < MinTrailSpace)
1233#undef DefTrailSpace
1234#define DefTrailSpace MinTrailSpace
1235#endif
1236
1237#if (DefStackSpace < MinStackSpace)
1238#undef DefStackSpace
1239#define DefStackSpace MinStackSpace
1240#endif
1241
1242#if (DefHeapSpace < MinHeapSpace)
1243#undef DefHeapSpace
1244#define DefHeapSpace MinHeapSpace
1245#endif
1246
1247#define DEFAULT_NUMBERWORKERS 1
1248#define DEFAULT_SCHEDULERLOOP 10
1249#define DEFAULT_DELAYEDRELEASELOAD 3
1250
1251X_API void YAP_FastInit(char *saved_state, int argc, char *argv[]) {
1252 YAP_init_args init_args;
1253 YAP_file_type_t out;
1254
1255 if ((out = Yap_InitDefaults(&init_args, saved_state, argc, argv)) !=
1256 YAP_FOUND_BOOT_ERROR)
1257 YAP_Init(&init_args);
1258 if (out == YAP_FOUND_BOOT_ERROR) {
1259 Yap_Error(init_args.ErrorNo, TermNil, init_args.ErrorCause);
1260 }
1261}
Main definitions.
const char * Yap_AbsoluteFile(const char *spec, bool ok)
generate absolute path, if ok first expand SICStus Prolog style
Definition: absf.c:145
X_API YAP_file_type_t YAP_parse_yap_arguments(int argc, char *argv[], YAP_init_args *iap)
Parse command line.
Definition: yap-args.c:607
X_API YAP_Term YAP_ReadClauseFromStream(int s, YAP_Term varNames, YAP_Term)
read a Prolog clause from a Prolog opened stream $s$
X_API bool YAP_DelayInit(YAP_ModInit_t f, const char s[])
YAP_DelayInit()
Definition: yap-args.c:1030
yap_error_descriptor_t * Yap_GetException(void)
clone Active Error
Definition: errors.c:1389
void * Malloc(size_t sz USES_REGS)
allocate a temporary text block
Definition: alloc.c:1759
@ argv
read-only atom, it describes the list with all arguments received by YAP at boot
Definition: YapGFlagInfo.h:89
all we need to know about an error/throw
Definition: YapError.h:205
yap_error_number errorNo
error identifier
Definition: YapError.h:207
char * classAsText
errorClass as text
Definition: YapError.h:213
char * errorAsText
errorNo as text
Definition: YapError.h:211
intptr_t errorLine
c-code that generated the error C-line
Definition: YapError.h:216