Prolog library: helper.pl
pereira at sri-unix.UUCP
pereira at sri-unix.UUCP
Mon Aug 15 15:52:46 AEST 1983
% File: Mec:Helper.Pl Author: R.A.O'Keefe Updated: 12 October 82
% Modified for TOPS-20 Fernando Pereira
% This file contains two utilities:
% try_hard_to_see(FileName, DeviceDefaults, ExtensionDefaults)
% -- tries all the Extension and Device defaults (varying the
% -- extensions first) until it succeeds in 'see'ing the file,
% -- and fails if the file cannot be found.
% give_help(Area, Topic)
% -- looks for an assertion help_file(Area, FileName, Delimiter)
% -- which you must supply. It then tries hard to open the file
% -- with default extensions "", "HLP", and "PL" and with device
% -- defaults "DSK", "MEC", "UTIL", and "PLL". If the file can't
% -- be found, or if there is no help_file assertion, it gives an
% -- apology. Otherwise it searches the file for the sequence
% -- Delimiter Topic ".", e.g. #help.
% It defines append, but its definition is the same as that in UTIL.
%----------------------------------------------------------------------%
:- public try_hard_to_see/3.
:- public append/3.
:- mode
try_hard_to_see(+, +, +),
expand_file(+, +, +, -),
parse_file(-, -, -, -, ?, ?),
file_component(-, ?, ?),
letter_or_digit(+, -),
normalise_file_component(+, +, -),
supply_file_default(+, +, +, -),
supply_file_default(+, +, -),
pack_file_title(+, +, +, +, -),
append(+, +, -).
try_hard_to_see(Title, DeviceDefaults, ExtensionDefaults) :-
nofileerrors,
expand_file(Title, DeviceDefaults, ExtensionDefaults, FullTitle),
see(FullTitle), !,
fileerrors.
try_hard_to_see(Title, _, _) :-
fileerrors,
write('** Can''t see '), writeq(Title), nl, fail.
expand_file(Title, DeviceDefaults, ExtensionDefaults, FullTitle) :-
atomic(Title),
name(Title, TitleName), !,
expand_file(TitleName, DeviceDefaults, ExtensionDefaults, FullTitle).
expand_file(Title, DeviceDefaults, ExtensionDefaults, FullTitle) :-
parse_file(Device, Directory, FileName, Extension, Title, []),
normalise_file_component(Directory, 99999, TryDirectory),
normalise_file_component(FileName, 99999, TryFileName), !,
supply_file_default(Device, DeviceDefaults, 99999, TryDevice),
supply_file_default(Extension, ExtensionDefaults, 99999, TryExtension),
pack_file_title(TryDevice, TryDirectory, TryFileName,
TryExtension, TryTitle),
name(FullTitle, TryTitle).
parse_file(Device, Directory, FileName, Extension) -->
( file_component(Device), ":"
| { Device = "" }
), !,
( "<", file_component(Directory), ">"
| { Directory = "" }
), !,
file_component(FileName),
( ".", file_component(Extension)
| { Extension = "" }
), !.
file_component([LetDig|Rest]) -->
[Char], { letter_or_digit(Char, LetDig)
| [Char] = "-", LetDig = Char }, !,
file_component(Rest).
file_component([]) --> [].
letter_or_digit(C, C) :-
C >= "0", C =< "9", !.
letter_or_digit(C, C) :-
C >= "a", C =< "z", !.
letter_or_digit(C, D) :-
C >= "A", C =< "Z",
D is C+("a"-"A").
normalise_file_component([], _, []) :- !.
normalise_file_component(Default, Length, TryThis) :-
atomic(Default),
name(Default, DefaultName), !,
normalise_file_component(DefaultName, Length, TryThis).
normalise_file_component(_, 0, []) :- !.
normalise_file_component([C|Rest], Length, [LetDig|More]) :-
letter_or_digit(C, LetDig), !,
Left is Length-1,
normalise_file_component(Rest, Left, More).
normalise_file_component([_|Rest], Length, TryThis) :-
normalise_file_component(Rest, Length, TryThis).
supply_file_default(Given, _, Length, TryThis) :-
normalise_file_component(Given, Length, TryThis).
supply_file_default([], Defaults, Length, TryThis) :-
supply_file_default(Defaults, Length, TryThis).
supply_file_default([Default|_], Length, TryThis) :-
normalise_file_component(Default, Length, TryThis).
supply_file_default([_|Defaults], Length, TryThis) :- !,
supply_file_default(Defaults, Length, TryThis).
pack_file_title([], [], FileName, Extension, Title) :- !,
append(FileName, [46|Extension], Title). % 46 is "."
pack_file_title([], Directory, FileName, Extension, Title) :- !,
pack_file_title([], [], FileName, Extension, Tail),
append([60|Directory],[62|Tail],Title). % 60 is "<"
% 62 is ">"
pack_file_title(Device, Directory, FileName, Extension, Title) :-
pack_file_title([], Directory, FileName, Extension, Tail),
append(Device, [58|Tail], Title). % 58 is ":"
append([Head|Tail], List, [Head|More]) :-
append(Tail, List, More).
append([], List, List).
%----------------------------------------------------------------------%
:- public give_help/0, give_help/1, give_help/2.
:- mode
give_help, % list of areas.
give_help(+), % list of topics in an area.
give_help(+, +), % help on a specific topic.
find_help(+, +), % find and type a topic of list
read_after_delimiter(+), % find "#" or return end_of_file
find_help(+, +, +), % check a list of topics
among(+, +), % member on commas instead of dots
type_until_delimiter(+). % display body of a Note.
give_help :-
write('Help is available in the following areas:'), nl,
help_file(Area, _, _),
tab(4), writeq(Area), nl,
fail.
give_help :-
write('Call give_help(Area) for a list of topics in an Area.'), nl,
write('Call give_help('), write('Area'),
write(',Topic) for help about a specific topic.'), nl.
give_help(Area) :-
write('The topics in '), writeq(Area),
write(' for which help is available are:'), nl,
give_help(Area, Topic),
write('Call give_help('), writeq(Area),
write(',Topic) for help about a specific topic.'), nl.
give_help(Area, Topic) :-
( help_file(Area, HelpName, Delimiter),
call(Delim is Delimiter)
| atom(Area),
Delim is "#", HelpName = Area
),
seeing(Old),
( try_hard_to_see(HelpName, [dsk,mec,util,pll], [hlp,pl]), !,
find_help(Delim, Topic),
seen,
see(Old)
| write('** No help is available on '), writeq(Topic),
write(' in '), writeq(Area), nl
), !.
find_help(Delimiter, Topic) :-
var(Topic), !,
read_after_delimiter(Delimiter, Topics),
( Topics = end_of_file
| tab(4), write(Topics), nl, fail
).
find_help(Delimiter, Topic) :-
read_after_delimiter(Delimiter, Topics),
find_help(Topics, Topic, Delimiter).
find_help(end_of_file, Topic, _) :- !,
seeing(HelpFile),
write('** No help is available on '), writeq(Topic),
write(' in file '), writeq(HelpFile), nl.
find_help(Topics, Topic, Delimiter) :-
among(Topic, Topics),
type_until_delimiter(Delimiter).
among(Topic, (Topics1,Topics2)) :- !,
( among(Topic, Topics1)
| among(Topic, Topics2)
).
among(Topic, (Topics1;Topics2)) :- !,
( among(Topic, Topics1)
| among(Topic, Topics2)
).
among(Topic, Topic).
read_after_delimiter(Delimiter, Topics) :-
repeat,
get0(Character),
( Character = 26, !, Topics = end_of_file
| Character = Delimiter, read(Topics)
).
type_until_delimiter(Delimiter) :-
get0(C),
C =\= 26, C =\= Delimiter,
put(C), !,
type_until_delimiter(Delimiter).
type_until_delimiter(Delimiter).
/* DEBUGGING CODE
is_string(X) :-
var(X), !, fail.
is_string([]) :- !.
is_string([H|_]) :-
\+ integer(H), !, fail.
is_string([9|T]) :-
is_string(T).
is_string([H|T]) :-
32 =< H, H < 127,
is_string(T).
portray_string([]) :-
put(34).
portray_string([34|T]) :-
put(34), put(34), !,
portray_string(T).
portray_string([H|T]) :-
put(H), !,
portray_string(T).
portray(X) :-
is_string(X),
put(34),
portray_string(X).
try(T) :-
expand_file(T, [dsk, mec, util, pll], [hlp, txt], Title),
writeq(Title), nl,
fail.
/* DEBUGGING CODE */
More information about the Comp.sources.unix
mailing list