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
module Pcre = Re_pcre
open ExtLib
open Dose_common
include Util.Logging (struct
let label = "dose_opencsw.packages"
end)
type name = string
type version = string
type vpkg = string
type package =
{ name : name;
version : version;
depends : vpkg list;
conflicts : vpkg list;
extras : (string * string) list
}
let default_package =
{ name = ""; version = ""; depends = []; conflicts = []; extras = [] }
module Set = Set.Make (struct
type t = package
let compare p1 p2 = compare (p1.name, p1.version) (p2.name, p2.version)
end)
let input_raw_priv parse_packages files =
let timer = Util.Timer.create "dose_opencsw.packages" in
Util.Timer.start timer ;
if List.length files > 1 then info "Merging input lists" ;
let s =
List.fold_left
(fun acc f ->
info "Parsing %s..." f ;
let l = parse_packages (fun x -> x) f in
List.fold_left (fun s x -> Set.add x s) acc l)
Set.empty
files
in
info "total packages %n" (Set.cardinal s) ;
Util.Timer.stop timer (Set.elements s)
exception Eof
let parse_paragraph pkg ch =
let line =
try IO.read_line ch with
| IO.No_more_input -> raise Eof
| End_of_file -> assert false
in
if ExtString.String.strip line = "" then None
else if ExtString.String.starts_with line "#" then None
else if
ExtString.String.starts_with line "-----BEGIN PGP SIGNED MESSAGE-----"
then None
else if ExtString.String.starts_with line "Hash: SHA1" then None
else if ExtString.String.starts_with line "-----BEGIN PGP SIGNATURE-----" then
raise Eof
else
let split s = ExtString.String.nsplit s "|" in
let catcherr a i =
try match split a.(i) with ["none"] -> [] | l -> l
with Invalid_argument _ -> []
in
let a = Array.of_list (ExtString.String.nsplit line " ") in
Some
{ pkg with
name = a.(2);
version = List.hd (Pcre.split ~rex:(Pcre.regexp ",") a.(1));
depends = catcherr a 6;
conflicts = catcherr a 8
}
let rec parse_packages_rec acc ch =
try
match parse_paragraph default_package ch with
| None -> parse_packages_rec acc ch
| Some par -> parse_packages_rec (par :: acc) ch
with Eof -> acc
let parse_packages_in _f ch = parse_packages_rec [] ch
let parse_packages _f filename =
try
let ch = Input.open_file filename in
let l = parse_packages_rec [] ch in
Input.close_ch ch ;
l
with Input.File_empty -> []
let input_raw files = input_raw_priv parse_packages files