# -*- prolog -*- # smallest # the smallest running program doing nothing main. # hello world # print a simple string on stdout main :- write('Hello World'), nl. # argv # access command line parameters (no segmentation fault accepted, nor silent exception, so some languages must explicitly check the presence of the argument) main :- current_prolog_flag(argv, CmdLine), append(_, [--, Arg1|_], CmdLine), write(Arg1), nl. # env # access environment variable main :- getenv('HOME', Home), write(Home), nl. # test file exists # return exit code error (non zero) if a file does not exist main :- exists_file('/etc/mtab') -> halt(0) ; halt(1). # test file readable # return exit code error (non zero) if a file is not readable main :- access_file('/etc/mtab', read) -> halt(0) ; halt(1). # formatting # print integers in a simple formatted string main :- A is 1, B is 2, Result is A + B, format('~d + ~d = ~d\n', [A, B, Result]). # system # call an external program and check the return value main :- shell('false', Status), (Status \= 0 -> current_stream(2, _, StdErr), format(StdErr, 'false failed~n', []) ; true), shell('echo done', _). # sed in place # remove #-comments from a file (modifying the file, i.e. in place) main :- getUserArg(1, File), atom_concat(File, '.tmp', TmpFile), strip_comments_from_file(File, TmpFile), delete_file(File), rename_file(TmpFile, File). strip_comments_from_file(FileIn, FileOut) :- open(FileIn, read, In, [type(binary)]), open(FileOut, write, Out, [type(binary)]), process_lines(In, Out), close(In), close(Out). process_lines(In, _) :- at_end_of_stream(In), !. process_lines(In, Out) :- read_line_to_codes(In, Line), partition(Line, 35, Prefix, _), format(Out, '~s~n', [Prefix]), !, process_lines(In, Out). partition(ListIn, Element, Prefix, Suffix) :- (member(Element, ListIn) -> append(Prefix, [Element|Suffix], ListIn) ; Prefix = ListIn, Suffix = []). getUserArg(N, Arg) :- current_prolog_flag(argv, Cmdline), append(_, [--|Args], Cmdline), nth1(N, Args, Arg). # compile what must be # find and compile .c files into .o when the .o is old or absent main :- expand_file_name('*.c', CFiles), forall(member(CFile, CFiles), (sub_atom(CFile, 0, _, 2, BaseName), atom_concat(BaseName, '.o', ObjFile), (should_compile(CFile, ObjFile) -> compile(CFile, ObjFile) ; true))). should_compile(SrcFile, ObjFile) :- (exists_file(ObjFile) -> time_file(SrcFile, SrcTime), time_file(ObjFile, ObjTime), ObjTime < SrcTime ; true). compile(SrcFile, ObjFile) :- concat_atom(['gcc -c "', SrcFile, '" -o "', ObjFile, '"'], '', Cmd), format('compiling ~w to ~w\n', [SrcFile, ObjFile]), trap(Cmd, _). trap(Cmd, Output) :- open(pipe(Cmd), read, Input), read_line_to_codes(Input, Output), close(Input).