Node:Loading Prolog Code, Previous:Initializing the Prolog Engine, Up:User-defined Main Programs



Loading Prolog Code

You can load your Prolog code with the call SP_load(). This is the C equivalent of the Prolog predicate load_files/1:

     int SP_load(char *filename)
     

Alternatively, you can restore a saved state with the call SP_restore(), which is the C equivalent of the Prolog predicate restore/1:

     int SP_restore(char *filename)
     

SP_load() and SP_restore() return SP_SUCCESS for success or SP_ERROR if an error condition occurred. The filename arguments in both functions are encoded strings.

Prolog error handling is mostly done by raising and catching exceptions. However, some faults are of a nature such that when they occur, the internal program state may be corrupted, and it is not safe to merely raise an exception. In runtime systems, the following C macro provides an environment for handling faults:

     int SP_on_fault(Stmt, Message, Cleanup)
     

which should occur in the scope of a char *Message declaration. Stmt is run, and if a fault occurs, Stmt is aborted, Message gets assigned a value explaining the fault, all queries and SP_term_refs become invalid, SICStus Prolog is reinitialized, and Cleanup run. If Stmt terminates normally, Message is left unchanged. For example, a "fault-proof" runtime system could have the structure:

     int main(int argc, char **argv)
     {
       char *message;
     
       SP_initialize(argc, argv, "/usr/local/lib/sicstus3.9.1/bin");
     loop:
       SP_on_fault(main_loop(), message,
                   {printf("ERROR: %s\n",message); goto loop;});
       exit(0);
     }
     
     main_loop()
     {...}
     

Faults that occur outside the scope of SP_on_fault() cause the runtime system to halt with an error message.

The following function can be used to raise a fault. For example, it can be used in a signal handler for SIGSEGV to prevent the program from dumping core in the event of a segmentation violation (runtime systems have no predefined signal handling):

     void SP_raise_fault(char *message)
     

As for most SICStus API functions, calling SP_raise_fault from a thread other than the main thread will lead to unpredictable results. For this reason, it is probably not a good idea to use SP_raise_fault in a signal handler unless the process is single threaded. Also note that SP_signal is not suitable for installing signal handlers for synchronous signals like SIGSEGV.