various fixes made when working with older gcc 3.2.3
[dyninst.git] / newtestsuite / src / specification / util.pl
1 % count(+From, +To, ?Value)
2 % unifies Value with the integers between From and To, inclusive
3 count(F,T,F) :- F =< T.
4 count(F,T,X) :- F < T, G is F + 1, count(G, T, X).
5
6 % int_list(+From, +To, ?List) unifies List with a list of integers between
7 % From and To, inclusive.
8 int_list(From, To, List) :-
9     findall(Int, count(From, To, Int), List).
10
11 % Eureka!  My generic list iterator!
12 % for_each(+List, +Variable, +Callable) unifies Variable with each element
13 % in List in turn, and then calls the term Callable with that binding, before
14 % backtracking, undoing the binding, and proceeding to the next element in the
15 % list.
16 for_each([], _, _).
17 for_each([Head | Tail], Variable, Callable) :-
18     (
19         Variable = Head,
20         call(Callable),
21         fail
22     );
23     for_each(Tail, Variable, Callable).
24
25 % I need a variant for_each that can do something different for the last
26 % element in a list.  Or a for_each_but_last.
27 % for_each/4
28 % for_each(+List, +Variable, +Callable1, +Callable2) unifies Variable with each
29 % element in List in turn, and calls the term Callable1 with that binding for
30 % all elements in List except for the last element.  for_each/4 calls Callable2
31 % with Variable bound to the last element in List, after all the other elements
32 % in the list have been handled.
33 for_each([], _, _, _).
34 for_each([Last], Variable, Callable1, Callable2) :-
35         (
36                 Variable = Last,
37                 call(Callable2),
38                 fail
39         );
40         for_each([], Variable, Callable1, Callable2).
41 for_each([Head | Tail], Variable, Callable1, Callable2) :-
42         Tail \= [],
43         (
44                 Variable = Head,
45                 call(Callable1),
46                 fail
47         );
48         for_each(Tail, Variable, Callable1, Callable2).
49
50 % strip_extension/2
51 % strip_extension(+Atom, ?Stripped)
52 strip_extension(Atom, Stripped) :-
53         findall(B, sub_atom(Atom, B, _, _, '.'), Bs),
54         max_list(Bs, M),
55         atom_chars(Atom, Achars),
56         prefix(Aprefix, Achars),
57         length(Aprefix, M),
58         atom_chars(Stripped, Aprefix).
59
60 % extension/2
61 % extension(+Atom, ?Ext)
62 extension(Atom, Ext) :-
63         findall(A, sub_atom(Atom, _, _, A, '.'), As),
64         min_list(As, M1),
65         M is M1 + 1,
66         atom_chars(Atom, Achars),
67         suffix(Asuffix, Achars),
68         length(Asuffix, M),
69         atom_chars(Ext, Asuffix).
70
71 % merge_lists/2
72 merge_lists([], []).
73 merge_lists([List], List).
74 merge_lists([List | Rest], Merged) :-
75         merge_lists(Rest, M1),
76         append(List, M1, Merged).
77         
78
79 % replace_chars_str/4
80 % replace_char_str(Str1, Str2, +Char1, +Char2)
81 replace_chars_str(Str1, Str2, Char1, Char2) :-
82         atom_chars(Str1, Str1l),
83         replace_chars_list(Str1l, Str2l, Char1, Char2),
84         atom_chars(Str2, Str2l).
85
86 replace_chars_list([], [], _, _).
87 replace_chars_list([C1 | T1], [C2 | T2], C1, C2) :-
88         replace_chars_list(T1, T2, C1, C2).
89 replace_chars_list([H1 | T1], [H1 | T2], C1, C2) :-
90         H1 \= C1,
91         replace_chars_list(T1, T2, C1, C2).
92
93 % write_list(+List, +Separator, +Stream)
94 write_list([], _, _).
95 write_list([I], _, Stream) :-
96     format(Stream, '~a', [I]).
97 write_list([H|T], Separator, Stream) :-
98     T \= [],
99     format(Stream, '~a~a', [H, Separator]),
100     write_list(T, Separator, Stream).
101
102 % write_list(+List, +Prefix, +Separator, +Suffix, +Stream)
103 write_list([], _, _, _, _).
104 write_list([Item], Prefix, _, Suffix, Stream) :-
105     format(Stream, '~a~a~a', [Prefix, Item, Suffix]).
106 write_list([Head | Tail], Prefix, Separator, Suffix, Stream) :-
107     Tail \= [],
108     format(Stream, '~a~a~a', [Prefix, Head, Separator]),
109     write_list_(Tail, Separator, Suffix, Stream).
110 % Utility predicate used by write_list/5
111 write_list_([I], _, Suffix, Stream) :-
112     format(Stream, '~a~a', [I, Suffix]).
113 write_list_([Head | Tail], Separator, Suffix, Stream) :-
114     Tail \= [],
115     format(Stream, '~a~a', [Head, Separator]),
116     write_list_(Tail, Separator, Suffix, Stream).
117
118 % map doesn't work
119 % map(+List, -Variable, -Template, +Callable, ?Out)
120 % Collects the results (from Template) of calling Callable with Variable
121 % bound to each of the values in List
122 map([], _, _, _, []).
123 map([Head | Tail], Variable, Template, Callable, Out) :-
124     (
125         map(Tail, Variable, Template, Callable, Recursive_results),
126         fail
127     );
128     Variable = Head,
129     findall(Template, Callable, Results),
130     append(Results, Recursive_results, Out).
131         
132     
133 % replace_suffix/4
134 % replace_suffix(+In, +Old, +New, ?Out)
135 % replace_suffix(?In, +Old, +New, +Out)
136 % Unifies Out with the atom In, after replacing the suffix Old in In with New
137 % If no matching suffix is found, the predicate fails.
138 % replace_suffix(+In, +Old, +New, ?Out)
139 replace_suffix(In, Old, New, Out) :-
140     nonvar(In), nonvar(Old), nonvar(New),
141     atom_length(Old, Old_length),
142     sub_atom(In, Root_length, Old_length, 0, Old),
143     sub_atom(In, 0, Root_length, Old_length, Root),
144     atom_concat(Root, New, Out).
145 % replace_suffix(?In, +Old, +New, +Out)
146 replace_suffix(In, Old, New, Out) :-
147     var(In), nonvar(Old), nonvar(New), nonvar(Out),
148     replace_suffix(Out, New, Old, In).
149
150 removedups([], []).
151 %removedups([H|T], Result) :- member(H, T), removedups(T, Result), !.
152 removedups([H|T], [H|T1]) :- (member(H, T) -> removedups(T, [H | T1]); removedups(T, T1)).