home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / plbin.zip / pl / src / pl-main.c < prev    next >
C/C++ Source or Header  |  1993-02-23  |  11KB  |  502 lines

  1. /*  pl-main.c,v 1.12 1993/02/23 13:16:37 jan Exp
  2.  
  3.     Copyright (c) 1990 Jan Wielemaker. All rights reserved.
  4.     See ../LICENCE to find out about your rights.
  5.     jan@swi.psy.uva.nl
  6.  
  7.     Purpose: Prologs main module
  8. */
  9.  
  10. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  11. Get the ball rolling.  The main task of  this  module  is  command  line
  12. option  parsing,  initialisation  and  handling  of errors and warnings.
  13. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  14.  
  15. #include "pl-incl.h"
  16. #include "pl-itf.h"
  17. #include "pl-save.h"
  18. #if unix || EMX
  19. #include <sys/param.h>
  20. #endif
  21.  
  22. forwards void    usage P((void));
  23. forwards char * findHome P((char *));
  24. forwards char *    findState P((char *));
  25.  
  26. #define    optionString(s) { if (argc > 1) \
  27.               { s = argv[1]; argc--; argv++; \
  28.               } else \
  29.                 usage(); \
  30.               break; \
  31.             }
  32.  
  33. static char *
  34. findHome(def)
  35. char *def;
  36. { char *h;
  37.  
  38.   if ( ExistsDirectory(def) )
  39.     return def;
  40.  
  41.   if ( (h=PrologPath(getenv("SWI_HOME_DIR"))) != NULL && ExistsDirectory(h) )
  42.     return store_string(h);
  43.  
  44. #if tos
  45.   { char *drv;
  46.     static char drvs[] = "cdefghijklmnopab";
  47.     char home[MAXPATHLEN];
  48.  
  49.     for(drv = drvs; *drv; drv++)
  50.     { sprintf(home, "%c:/pl", *drv);
  51.       if ( Drvmap() & (1 << (*drv - 'a')) && ExistsDirectory(home) )
  52.         return store_string(home);
  53.     }
  54.   }
  55. #endif
  56.  
  57.   fatalError("Can't find Prolog Home Directory");
  58.   return (char *) NULL;
  59. }
  60.  
  61. /*
  62.   -- atoenne -- convert state to an absolute path. This allows relative
  63.   SWI_HOME_DIR and cleans up non-canonical paths.
  64. */
  65.  
  66. static char *
  67. findState(base)
  68. char *base;
  69. { char state[MAXPATHLEN];
  70.   char *full;
  71.  
  72.   sprintf(state, "%s.%s", base, systemDefaults.machine);
  73.   if ( ExistsFile(state) )
  74.     return store_string(state);
  75.  
  76.   if ( ExistsFile(base) )
  77.     return store_string(base);
  78.  
  79.   sprintf(state, "%s/startup/%s.%s",
  80.       systemDefaults.home, base, systemDefaults.machine);
  81.   full = AbsoluteFile(state);
  82.   if ( ExistsFile(full) )
  83.     return store_string(full);
  84.  
  85.   sprintf(state, "%s/startup/%s", systemDefaults.home, base);
  86.   full = AbsoluteFile(state);
  87.   if ( ExistsFile(full) )
  88.     return store_string(full);
  89.  
  90.   return base;
  91. }
  92.  
  93.  
  94. #if O_LINK_PCE
  95. foreign_t
  96. pl_pce_init()
  97. { prolog_pce_init(mainArgc, mainArgv);
  98.  
  99.   succeed;
  100. }
  101. #endif
  102.  
  103. int
  104. startProlog(argc, argv, env)
  105. int argc;
  106. char **argv;
  107. char **env;
  108. { char *s;
  109.   int n;
  110.   char *state;
  111.   bool compile;
  112.  
  113.   mainArgc            = argc;
  114.   mainArgv            = argv;
  115.   mainEnv            = env;
  116.  
  117.  /* status.debugLevel = 9; */
  118.  
  119.   if ( status.dumped == FALSE )
  120.   { systemDefaults.machine        = MACHINE;
  121.     systemDefaults.home            = findHome(store_string(PrologPath(SYSTEMHOME)));
  122.     systemDefaults.state        = findState("startup");
  123.     systemDefaults.startup        = store_string(PrologPath(DEFSTARTUP));
  124.     systemDefaults.version        = store_string(PLVERSION);
  125.     systemDefaults.local        = DEFLOCAL;
  126.     systemDefaults.global        = DEFGLOBAL;
  127.     systemDefaults.trail        = DEFTRAIL;
  128.     systemDefaults.argument        = DEFARGUMENT;
  129.     systemDefaults.lock            = DEFLOCK;
  130.     systemDefaults.goal            = "'$welcome'";
  131.     systemDefaults.toplevel        = "prolog";
  132.     systemDefaults.notty        = FALSE;
  133.     systemDefaults.operating_system = OPERATING_SYSTEM;
  134.  
  135.   } else
  136.   { DEBUG(1, printf("Restarting from dumped state\n"));
  137.     SECURE( extern char *sbrk();
  138.         extern char *thebreak;
  139.         if ( thebreak != (char *)sbrk(0) )
  140.           printf("Saved break = %ld; reloaded = %ld\n", thebreak, sbrk(0))
  141.       );
  142.   }
  143.  
  144.   SECURE(
  145.     malloc_debug(1);
  146.     if ( malloc_verify() != 1 )
  147.       sysError("Memory allocation corrupted");
  148.   );
  149.  
  150.   compile            = FALSE;
  151.   state                = systemDefaults.state;
  152.   status.io_initialised        = FALSE;
  153.   status.initialised        = FALSE;
  154.   status.notty            = systemDefaults.notty;
  155.   status.boot            = FALSE;
  156.   status.extendMode        = TRUE;
  157.  
  158.   argc--; argv++;
  159.  
  160.   if ( (s = getenv("EMACS")) != NULL && streq(s, "t") )
  161.     status.notty = TRUE;
  162.  
  163.   for(n=0; n<argc; n++)            /* need to check this first */
  164.   { DEBUG(2, printf("argv[%d] = %s\n", n, argv[n]));
  165.     if (streq(argv[n], "-b") )
  166.       status.boot = TRUE;
  167.   }
  168.  
  169.   DEBUG(1, {if (status.boot) printf("Boot session\n");});
  170.  
  171.   if ( argc >= 2 && streq(argv[0], "-r") )
  172.   { loaderstatus.restored_state = lookupAtom(AbsoluteFile(PrologPath(argv[1])));
  173.     argc -= 2, argv += 2;        /* recover; we've done this! */
  174.   }
  175.  
  176.   if ( argc >= 2 && streq(argv[0], "-x") )
  177.   { state = argv[1];
  178.     argc -= 2, argv += 2;
  179.     DEBUG(1, printf("Startup file = %s\n", state));
  180.   }
  181.  
  182.   if ( argc >= 1 && streq(argv[0], "-help") )
  183.     usage();
  184.  
  185. #define K * 1024L
  186.  
  187.   if ( state != NULL && status.boot == FALSE )
  188.   { DEBUG(1, printf("Scanning %s for options\n", state));
  189.     if ( loadWicFile(state, TRUE, TRUE) == FALSE )
  190.       Halt(1);
  191.     DEBUG(2, printf("options.localSize    = %ld\n", options.localSize));
  192.     DEBUG(2, printf("options.globalSize   = %ld\n", options.globalSize));
  193.     DEBUG(2, printf("options.trailSize    = %ld\n", options.trailSize));
  194.     DEBUG(2, printf("options.argumentSize = %ld\n", options.argumentSize));
  195.     DEBUG(2, printf("options.lockSize      = %ld\n", options.lockSize));
  196.     DEBUG(2, printf("options.goal         = %s\n",  options.goal));
  197.     DEBUG(2, printf("options.topLevel     = %s\n",  options.topLevel));
  198.     DEBUG(2, printf("options.initFile     = %s\n",  options.initFile));
  199.   } else
  200.   { options.compileOut      = "a.out";
  201.     options.localSize      = systemDefaults.local    K;
  202.     options.globalSize      = systemDefaults.global   K;
  203.     options.trailSize      = systemDefaults.trail    K;
  204.     options.argumentSize  = systemDefaults.argument K;
  205.     options.lockSize      = systemDefaults.lock        K;
  206.     options.goal      = systemDefaults.goal;
  207.     options.topLevel      = systemDefaults.toplevel;
  208.     options.initFile      = systemDefaults.startup;
  209.   }
  210.  
  211.   for( ; argc > 0 && (argv[0][0] == '-' || argv[0][0] == '+'); argc--, argv++ )
  212.   { if ( streq(&argv[0][1], "tty") )
  213.     { status.notty = (argv[0][0] == '-');
  214.       continue;
  215.     }
  216.  
  217.     s = &argv[0][1];
  218.     while(*s)
  219.     { switch(*s)
  220.       { case 'd':    if (argc > 1)
  221.             { status.debugLevel = atoi(argv[1]);
  222.               argc--, argv++;
  223.             } else
  224.               usage();
  225.             break;
  226.     case 'O':    status.optimise = TRUE;
  227.             break;
  228.       case 'o':    optionString(options.compileOut);
  229.     case 'f':    optionString(options.initFile);
  230.     case 'g':    optionString(options.goal);
  231.     case 't':    optionString(options.topLevel);
  232.     case 'c':    compile = TRUE;
  233.             break;
  234.     case 'b':    status.boot = TRUE;
  235.             break;
  236.     case 'B':
  237. #if !O_DYNAMIC_STACKS
  238.             options.localSize    = 32 K;
  239.             options.globalSize   = 8 K;
  240.             options.trailSize    = 8 K;
  241.             options.argumentSize = 1 K;
  242.             options.lockSize     = 1 K;
  243. #endif
  244.             goto next;
  245.     case 'L':    options.localSize    = atoi(++s) K; goto next;
  246.     case 'G':    options.globalSize   = atoi(++s) K; goto next;
  247.     case 'T':    options.trailSize    = atoi(++s) K; goto next;
  248.     case 'A':    options.argumentSize = atoi(++s) K; goto next;
  249.     case 'P':    options.lockSize     = atoi(++s) K; goto next;
  250.       }
  251.       s++;
  252.     }
  253.     next:;
  254.   }
  255. #undef K
  256.   
  257.   DEBUG(1, printf("Command line options parsed\n"));
  258.  
  259.   setupProlog();
  260.  
  261. #if LINK_THIEF
  262.   { extern long pl_thief();
  263.  
  264.     if ( status.dumped == FALSE )
  265.       PL_register_foreign("$thief", 1, pl_thief, 0);
  266.   }
  267. #endif
  268.  
  269.   systemMode(TRUE);
  270.  
  271.   if ( status.boot )
  272.   { if (compileFileList(options.compileOut, argc, argv) == TRUE)
  273.       Halt(0);
  274.  
  275.     Halt(1);
  276.   }
  277.  
  278.   if ( state != NULL )
  279.   { status.boot = TRUE;
  280.     if ( loadWicFile(state, TRUE, FALSE) == FALSE )
  281.       Halt(1);
  282.     status.boot = FALSE;
  283.   }
  284.  
  285.   if ( PL_foreign_reinit_function != NULL )
  286.     (*PL_foreign_reinit_function)(mainArgc, mainArgv);
  287.  
  288.   systemMode(FALSE);
  289.   status.dumped = TRUE;
  290.   status.initialised = TRUE;
  291.  
  292. #if O_LINK_PCE
  293.   PL_register_foreign("$pce_init", 0, pl_pce_init, PL_FA_TRANSPARENT, 0);
  294. #endif
  295.  
  296.   DEBUG(1, printf("Starting Prolog Engine\n"));
  297.  
  298.   if ( prolog(PL_new_atom(compile ? "$compile" : "$init")) == TRUE )
  299.     Halt(0);
  300.   else
  301.     Halt(1);
  302.  
  303.   return 0;
  304. }
  305.  
  306. static void
  307. usage()
  308. { static char *lines[] = {
  309.     "%s: Usage:\n",
  310.     "    1) %s -help\n",
  311.     "    2) %s [options]\n",
  312.     "    3) %s [options] [-o output] -c file ...\n",
  313.     "    4) %s [options] [-o output] -b file ...\n",
  314.     "Options:\n",
  315.     "    -x state        Start from state (must be first)\n",
  316.     "    -[LGTA]kbytes   Specify [Local, Global, Trail, Argument] stack sizes\n",
  317.     "    -B              Small stack sizes to prepare for boot\n",
  318.     "    -t toplevel     Toplevel goal\n",
  319.     "    -g goal         Initialisation goal\n",
  320.     "    -f file         Initialisation file\n",
  321.     "    [+/-]tty        Allow tty control\n",
  322.     "    -O              Optimised compilation\n",
  323.     NULL
  324.   };
  325.   char **lp = lines;
  326.  
  327.   for(lp = lines; *lp; lp++)
  328.     fprintf(stderr, *lp, BaseName(mainArgv[0]));
  329.  
  330.   Halt(1);
  331. }
  332.  
  333. #if ANSI
  334. #include <stdarg.h>
  335.  
  336. bool
  337. sysError(char *fm, ...)
  338. { va_list args;
  339.  
  340.   va_start(args, fm);
  341.   vsysError(fm, args);
  342.   va_end(args);
  343.  
  344.   PL_fail;
  345. }
  346.  
  347. bool
  348. fatalError(char *fm, ...)
  349. { va_list args;
  350.  
  351.   va_start(args, fm);
  352.   vfatalError(fm, args);
  353.   va_end(args);
  354.  
  355.   PL_fail;
  356. }
  357.  
  358. bool
  359. warning(char *fm, ...)
  360. { va_list args;
  361.  
  362.   va_start(args, fm);
  363.   vwarning(fm, args);
  364.   va_end(args);
  365.  
  366.   PL_fail;
  367. }
  368. #else
  369. #if mips
  370. #include "/usr/include/varargs.h"
  371. #else
  372. #include <varargs.h>
  373. #endif
  374.  
  375. bool
  376. sysError(va_alist)
  377. va_dcl
  378. { va_list args;
  379.   char *fm;
  380.  
  381.   va_start(args);
  382.   fm = va_arg(args, char *);
  383.   vsysError(fm, args);
  384.   va_end(args);
  385.  
  386.   PL_fail;
  387. }
  388.  
  389. bool
  390. fatalError(va_alist)
  391. va_dcl
  392. { va_list args;
  393.   char *fm;
  394.  
  395.   va_start(args);
  396.   fm = va_arg(args, char *);
  397.   vfatalError(fm, args);
  398.   va_end(args);
  399.  
  400.   PL_fail;
  401. }
  402.  
  403. bool
  404. warning(va_alist)
  405. va_dcl
  406. { va_list args;
  407.   char *fm;
  408.  
  409.   va_start(args);
  410.   fm = va_arg(args, char *);
  411.   vwarning(fm, args);
  412.   va_end(args);
  413.  
  414.   PL_fail;
  415. }
  416. #endif /* ANSI */
  417.  
  418. bool
  419. vsysError(fm, args)
  420. char *fm;
  421. va_list args;
  422. { fprintf(stderr, "[PROLOG INTERNAL ERROR:\n\t");
  423.   vfprintf(stderr, fm, args);
  424.   fprintf(stderr, "\n[Switched to system mode: style_check(+dollar)]\n");
  425.   debugstatus.styleCheck |= DOLLAR_STYLE;
  426.   fprintf(stderr, "PROLOG STACK:\n");
  427.   backTrace(NULL, 10);
  428.   fprintf(stderr, "]\n");
  429.  
  430.   pl_abort();
  431.   Halt(3);
  432.   PL_fail;
  433. }
  434.  
  435. bool
  436. vfatalError(fm, args)
  437. char *fm;
  438. va_list args;
  439. { fprintf(stderr, "[FATAL ERROR:\n\t");
  440.   vfprintf(stderr, fm, args);
  441.   fprintf(stderr, "]\n");
  442.  
  443.   Halt(2);
  444.   PL_fail;
  445. }
  446.  
  447. bool
  448. vwarning(fm, args)
  449. char *fm;
  450. va_list args;
  451. { toldString();
  452.  
  453.   if ( ReadingSource && !status.boot && status.initialised )
  454.   { word goal = globalFunctor(FUNCTOR_exception3);
  455.     char message[LINESIZ];
  456.     word arg;
  457.  
  458.     vsprintf(message, fm, args);
  459.  
  460.     unifyAtomic(argTermP(goal, 0), ATOM_warning);
  461.     unifyFunctor(argTermP(goal, 1), FUNCTOR_warning3);
  462.     arg = argTerm(goal, 1);
  463.     unifyAtomic(argTermP(arg, 0), source_file_name);
  464.     unifyAtomic(argTermP(arg, 1), consNum(source_line_no));
  465.     unifyAtomic(argTermP(arg, 2), globalString(message));
  466.  
  467.     if ( callGoal(MODULE_user, goal, FALSE) == FALSE )
  468.     { extern int Output;
  469.       int old = Output;
  470.     
  471.       Output = 2;
  472.       Putf("[WARNING: (%s:%d)\n\t",
  473.         stringAtom(source_file_name), source_line_no);
  474.       vPutf(fm, args);
  475.       Putf("]\n");
  476.       Output = old;
  477.     }
  478.  
  479.     PL_fail;                /* handled */
  480.   }
  481.  
  482.  
  483.   if ( status.io_initialised )
  484.   { extern int Output;
  485.     int old = Output;
  486.     
  487.     Output = 2;
  488.     Putf("[WARNING: ");
  489.     vPutf(fm, args);
  490.     Putf("]\n");
  491.     Output = old;
  492.   } else
  493.   { fprintf(stderr, "[WARNING: ");
  494.     vfprintf(stderr, fm, args);
  495.     fprintf(stderr, "]\n");
  496.   }
  497.  
  498.   pl_trace();
  499.  
  500.   PL_fail;
  501. }
  502.