Source file packages.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
(** Representation of a PEF stanza. *)
module Pcre = Re_pcre
open ExtLib
open Dose_common
open Dose_extra
include Util.Logging (struct
let label = "dose_pef.packages"
end)
exception IgnorePackage of string
let lexbuf_wrapper type_parser v =
Format822.lexbuf_wrapper type_parser Packages_lexer.token_deb v
let parse_name v = lexbuf_wrapper Packages_parser.pkgname_top v
let parse_version v = lexbuf_wrapper Packages_parser.version_top v
let parse_vpkg v = lexbuf_wrapper Packages_parser.vpkg_top v
let parse_vpkglist v = lexbuf_wrapper Packages_parser.vpkglist_top v
let parse_vpkgformula v = lexbuf_wrapper Packages_parser.vpkgformula_top v
let parse_archlist v = lexbuf_wrapper Packages_parser.archlist_top v
let parse_builddepslist v = lexbuf_wrapper Packages_parser.builddepslist_top v
let parse_builddepsformula v =
lexbuf_wrapper Packages_parser.builddepsformula_top v
let rec assoc (n : string) = function
| (k, v) :: _ when k = n -> v
| (_, _) :: t -> assoc n t
| [] -> raise Not_found
let parse_s ?default ?(required = false) f label par =
try
let (_loc, s) = assoc label par in
f (label, (_loc, s))
with Not_found -> (
match (required, default) with
| (false, None) -> raise Not_found
| (true, None) ->
raise (Format822.ParseError ([], label, "This label is required."))
| (_, Some d) -> d)
let parse_string (_, (_, s)) = s
let parse_int (_, (_, s)) = int_of_string s
let parse_string_opt (_, (_, s)) = match s with "" -> None | _ -> Some s
let blank_regexp = Pcre.regexp "[ \t]+"
let comma_regexp = Pcre.regexp "[ \t]*,[ \t]*"
let parse_string_list ?(rex = blank_regexp) (_, (_, s)) =
match Pcre.split ~rex s with [] -> raise Not_found | l -> l
let parse_bool (label, (_, s)) =
match s with
| "Yes" | "yes" | "True" | "true" -> true
| "No" | "no" | "False" | "false" -> false
| s -> raise (Format822.Type_error (label ^ " - wrong value : " ^ s))
let parse_bool_s v = string_of_bool (parse_bool v)
let parse_int_s (_, (_, s)) = string_of_int (int_of_string s)
let parse_e par =
List.filter_map
(fun (label, p) ->
try
match p with
| None -> Some (label, parse_s parse_string label par)
| Some parse_f -> Some (label, parse_f label par)
with Not_found -> None)
extras
let get_field_value ~parse ~par ~field:(label, value) =
let res =
if Option.is_none value then parse label par else Option.get value
in
(label, res)
(** strip down version of the debian package format *)
class package ?(name = ("Package", None)) ?(version = ("Version", None))
?(installed = ("Installed", Some false)) ?(depends = ("Depends", None))
?(conflicts = ("Conflicts", None)) ?(provides = ("Provides", None))
?(recommends = ("Recommends", None)) ?( = ([], None)) par =
object
val name : string * Packages_types.name =
let parse = parse_s ~required:true parse_name in
get_field_value ~parse ~par ~field:name
val version : string * Packages_types.version =
let parse = parse_s ~required:true parse_version in
get_field_value ~parse ~par ~field:version
val installed : string * Packages_types.installed =
let parse = parse_s ~default:false parse_bool in
get_field_value ~parse ~par ~field:installed
val depends : string * Packages_types.vpkgformula =
let parse = parse_s ~default:[] parse_vpkgformula in
get_field_value ~parse ~par ~field:depends
val conflicts : string * Packages_types.vpkglist =
let parse = parse_s ~default:[] parse_vpkglist in
get_field_value ~parse ~par ~field:conflicts
val provides : string * Packages_types.vpkglist =
let parse = parse_s ~default:[] parse_vpkglist in
get_field_value ~parse ~par ~field:provides
val recommends : string * Packages_types.vpkgformula =
let parse = parse_s ~default:[] parse_vpkgformula in
get_field_value ~parse ~par ~field:recommends
val extras : (string * string) list =
match extras with
| ([], None) -> []
| (, None) -> parse_e extras par
| ([], Some l) -> l
| (, Some l) -> l @ parse_e extras par
method name = snd name
method version = snd version
method installed = snd installed
method depends = snd depends
method conflicts = snd conflicts
method provides = snd provides
method recommends = snd recommends
method extras = extras
method add_extra k v = {<extras = (k, v) :: extras>}
method get_extra k = assoc k extras
method set_extras v = {<extras = v>}
method set_installed v = {<installed = (fst installed, v)>}
method pp oc =
Printer.pp_string_wl oc name ;
Printer.pp_string_wl oc version ;
Printer.pp_vpkglist_wl oc provides ;
Printer.pp_vpkgformula_wl oc depends ;
Printer.pp_vpkglist_wl oc conflicts ;
Printer.pp_vpkgformula_wl oc recommends ;
Printf.fprintf oc "\n"
end
let parse_package_stanza ~filter ~ par =
let p () = new package ~extras:(extras, None) par in
if Option.is_none filter then Some (p ())
else if (Option.get filter) par then Some (p ())
else None
let packages_parser fname stanza_parser p =
let rec packages_parser_aux fname stanza_parser acc p =
let filename =
("Filename", (Format822.dummy_loc, Filename.basename fname))
in
match
Format822_parser.stanza_822 Format822_lexer.token_822 p.Format822.lexbuf
with
| None -> acc
| Some stanza -> (
match stanza_parser (filename :: stanza) with
| None -> packages_parser_aux fname stanza_parser acc p
| Some st -> packages_parser_aux fname stanza_parser (st :: acc) p)
in
packages_parser_aux fname stanza_parser [] p
let parse_packages_in ?filter ?( = []) fname ic =
info "Parsing 822 file %s..." fname ;
try
let stanza_parser = parse_package_stanza ~filter ~extras in
Format822.parse_from_ch (packages_parser fname stanza_parser) ic
with Format822.ParseError (cl, label, errmsg) ->
fatal
"Filename %s\n %s\n %s : %s"
fname
(String.concat "\n " cl)
label
errmsg
module Set = struct
let pkgcompare p1 p2 = compare (p1#name, p1#version) (p2#name, p2#version)
include Set.Make (struct
type t = package
let compare (x : t) (y : t) = pkgcompare x y
end)
end
let input_raw ?( = []) =
let module M = Format822.RawInput (Set) in
M.input_raw (parse_packages_in ~extras)
let input_raw_in ?( = []) =
let module M = Format822.RawInput (Set) in
M.input_raw_in (parse_packages_in ~extras)