(* Copyed from the portal, doesn't exactly go out this in the most
direct way, or does it? *)
-fun exists name =
- validName name andalso let
- val proc = Unix.execute ("/usr/bin/apt-cache", ["show", name])
- val inf = Unix.textInstreamOf proc
-
- val _ = TextIO.inputLine inf (* in every let* lies an imperative program in disguise *)
-
- fun loop _ =
- case TextIO.inputLine inf of
- NONE => false
- | SOME line =>
- if size line >= 9 andalso String.substring (line, 0, 9) = "Section: " then
- true
- else if size line >= 13 andalso String.substring (line, 0, 13) = "Description: " then
- false
- else
- loop ()
- in
- loop ()
- before ignore (Unix.reap proc)
- end
+fun info name =
+ if not (validName name) then
+ NONE
+ else
+ let
+ val proc = Unix.execute ("/usr/bin/apt-cache", ["show", name])
+ val inf = Unix.textInstreamOf proc
+
+ val _ = TextIO.inputLine inf (* in every let* lies an imperative program in disguise *)
+
+ fun loop (section, descr) =
+ case TextIO.inputLine inf of
+ NONE => (section, descr)
+ | SOME line =>
+ if size line >= 9 andalso String.substring (line, 0, 9) = "Section: " then
+ loop (SOME (String.substring (line, 9, size line - 10)), descr)
+ else if size line >= 13 andalso String.substring (line, 0, 13) = "Description: " then
+ loop (section, SOME (String.substring (line, 13, size line - 14)))
+ else if size line >= 16 andalso String.substring (line, 0, 16) = "Description-en: " then
+ loop (section, SOME (String.substring (line, 16, size line - 17)))
+ else
+ loop (section, descr)
+ in
+ (case loop (NONE, NONE) of
+ (SOME section, SOME descr) => SOME {section = section, description = descr}
+ | _ => NONE)
+ before ignore (Unix.reap proc)
+ end
fun installed name =
validName name