1:- module( upsh, [upsh_make/0,upsh_make/1,upsh_version/1,upsh_version/2] ). 2 3:- ensure_loaded( '../src/upsh_version' ). 4 5upsh_make_defaults( Defs ) :- 6 current_prolog_flag( home, SwiHome ), 7 % 1st place to look: ../../bin/swipl relative to flag home 8 file_directory_name( SwiHome, SwiLib ), 9 file_directory_name( SwiLib, BaseD ), 10 directory_file_path( BaseD, bin, BinD ), 11 Exec = upsh, 12 ( exists_directory(BinD) -> 13 Defs = [exec(Exec),bin_dir(BinD)] 14 ; 15 write( unable_to_locate_bin_dir_for_upsh__use_option(bin_dir) ), nl, 16 Defs = [exec(Exec)] 17 ).
Opts
current_prolog_flag( home, Home ).252upsh_make :- 253 upsh_make( [] ). 254 255upsh_make( ArgS ) :- 256 debug( upsh(make), 'making new upsh executable', [] ), % we don't expect this to show 257 debug( upsh(make) ), 258 \+ var(ArgS), 259 ( is_list(ArgS) -> Args = ArgS; Args = [ArgS] ), 260 upsh_make_defaults( Defs ), 261 append( Args, Defs, Opts ), 262 multifile( upsh_built_call/1 ), 263 dynamic( upsh_built_call/1 ), 264 asserta( upsh_built_call(true) ), 265 load_files( pack('upsh/src/upsh') ), 266 memberchk( exec(Exec), Opts ), 267 memberchk( bin_dir(BinD), Opts ), 268 directory_file_path( BinD, Exec, AbsExec ), 269 % 25.11.14, set_prolog_flag(toplevel_thread,true) avoids [Thread main] Prefix in error messages. 270 qsave_program( AbsExec, [init_file(none_what_noever),goal((set_prolog_flag(toplevel_thread,true),upsh_exec:upsh))] ), 271 nodebug( upsh(make) ), 272 abolish( upsh_built_call/1 ). 273 274/* pre 18.12.10: 275upsh_make( ArgS ) :- 276 \+ var(ArgS), 277 ( is_list(ArgS) -> Args = ArgS; Args = [ArgS] ), 278 upsh_make_defaults( Defs ), 279 append( Args, Defs, Opts ), 280 % delete_local_exec, 281 once( absolute_file_name( pack(upsh), UpshD ) ), 282 % working_directory( Old, UpshD ), 283 % Shell ='swipl -f upsh_create.pl -g upsh_create', 284 debug( upsh, 'Shelling: ~w', Shell ), 285 shell( Shell ), 286 memberchk( exec(Exec), Opts ), 287 memberchk( bin_dir(BinD), Opts ), 288 directory_file_path( BinD, Exec, PathTo ), 289 % rename_file( 'bin/upsh', PathTo ), 290 atom_concat( 'mv bin/upsh ', PathTo, MvTo ), 291 shell( MvTo ), 292 debug( upsh, 'Moved to: ~p', PathTo ), 293 working_directory( _, Old ), 294 debug( upsh, 'Done', true ). 295 */ 296 297delete_local_exec :- 298 Loc = 'bin/upsh', 299 exists_file( Loc ), 300 !, 301 delete_file( Loc ). 302delete_local_exec
Unix to Prolog shell.
Upsh 3.0
Upsh stands for Unix to Prolog shell. It is a Prolog program which can be used to run Prolog programs from the command line or as scripts. It originally ran on three Prolog engines without changes to the source code. Current versions are only tested on SWI-Prolog.
With version 3, Upsh has all the features I had envisaged and many which I just thought of on the way. It is also fairly stable and actively maintained. The development has now been switched to SWI and upsh is also provided as an easy to install SWI pack.
The pack has a single main predicate which creates an executable state that provides a convenient way of executing prolog scripts from the command line (cli = command line interaction/invocation). The state can be invoked by calling the created executable (upsh) on command line. By default the upsh binary is placed in same directory as the swipl executable. Only tested on Linux.
Installation and Testing
This should also create the executable (upsh). The executable can be also be created explicitly with:
Ask your shell to re-read its executables with something like rehash, and the upsh executable should be on your path.
Locating Scripts
The executable will look for scripts via the following mechanisms.
Named Scripts
A command line invocation like
names the script say so
upshwill look for a prolog filesay.pl.To locate this,
upshwill first look in current directory, then in$HOME/bin/cline_upsh/and finally in PACK/scripts directory of all installed packs. The last of those is how in the above exampleupshcan locate scriptsay.plin installed pack$HOME/.local/share/swi-prolog/pack/upsh/scripts/say.pl.Missing Script Names
When no script name is given
upshwill try to infer one.Select the single .pl file in current directory.
If multiple .pl files exist in current directory select the one that shares its basename with the directory name.
As of v3 users can define a predicate for auto locating scripts in
user_profile(upsh_script_sel.pl)defining upsh_script_sel/1 which should return the name of the script.The idea is that the predicate will look into the current directory and recognise the type of operation that is required.
For instance, in directories with a single .tex file named submit.tex in them, my locator predicate will select the script that runs pdflatex and a pdf viewer on the produced output.
So, in this scenario the user can simply call
Entry Predicate
Once the input program/script has be loaded,
upshwill call the entry predicate possibly passing any OS arguments that are meant for the script as input.For a program such as, _|
say.pl, the default behaviour is to look for defined predicate say/0, say/1, say/n, main/0, main/1, and main/n. It will then call the first of those that is defined and matches any passing arguments. In the case of arity one predicates, if there are multiple arguments to be passed, then they will be passed as a single list.Argument Passing
Upsh by default converts OS arguments to Prolog terms:
\\ escapes elements of construction of terms
To pass term functor =, you can also use ==
To terminate nested arguments use ":"
Variables can be passed to the script and identified.
> upsh say p a alpha=beta,X gamma=delta=atm=Y alpha(beta,_1088) gamma(delta('Y')) upsh_vs(['X'=_1088])To avoid translation of Program arguments
To edit the Program source file
Upsh flags
The executable takes a number of one letter flags:
Pack Information
If you use Upsh for a while I would appreciate an email with the kind of scripts you using it with, at http://stoics.org.uk/~nicos/sware/contact.html
upsh_script_sel.pl, and singleton .pl load in presence of args, redone docs */