~ubuntu-branches/ubuntu/precise/build-essential/precise

« back to all changes in this revision

Viewing changes to list2depends.lhs

  • Committer: Bazaar Package Importer
  • Author(s): Antti-Juhani Kaijanaho
  • Date: 2002-02-17 16:07:22 UTC
  • Revision ID: james.westby@ubuntu.com-20020217160722-czamutt6zgfvt1qy
Tags: 6
* ran "make make-esslist", again.
* debian/rules: Install list into $(sharedir),
  and install a symlink from there to $(docdir),
  closes: #134390.
* Updated debian/librules.mk.
* debian/control: Updated Standards-Version to 3.5.6.
* debian/copyright: Updated copyright year list.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/runhugs
 
2
 
 
3
This program converts the Build-Essential (bess) list into a form
 
4
suitable for use in a Debian Depends control field.
 
5
 
 
6
> module Main (main) where
 
7
 
 
8
Due to problems with the Emacs Haskell major mode (see Bug#46115), the
 
9
string constants that include a certain magic word are imported from
 
10
another file.
 
11
 
 
12
> import Constants
 
13
 
 
14
> import Maybe
 
15
> import System
 
16
 
 
17
The list we are parsing is quite free-form.  Everything up to a
 
18
certain line (beginConstant) and everything after another certain line
 
19
(endConstant) are ignored, as is everything that is indented.  The
 
20
function bessDeComment filters out these comments; deComment weeds out
 
21
indented lines and stripSurroundings removes the head and the tail.
 
22
 
 
23
> bessDeComment :: String -> String
 
24
> bessDeComment = unlines . deComment . stripSurroundings . lines
 
25
>     where deComment :: [String] -> [String]
 
26
>           deComment = filter (not . isComment)
 
27
>               where isComment :: String -> Bool
 
28
>                     isComment [] = True
 
29
>                     isComment (c:_) = c == ' ' || c == '\t'
 
30
>           stripSurroundings :: [String] -> [String]
 
31
>           stripSurroundings = stripTail . stripHead
 
32
>           stripHead :: [String] -> [String]
 
33
>           stripHead = tail . dropWhile (/= beginConstant)
 
34
>           stripTail = takeWhile (/= endConstant)
 
35
 
 
36
The list contains entries that are meant for only some Debian
 
37
architectures.  filterByArchitecture assumes de-commented input and
 
38
outputs the input without those parts that are not meant for the
 
39
current architecture (which is given as the first argument to this
 
40
function).
 
41
 
 
42
> filterByArchitecture :: String -> String -> String
 
43
> filterByArchitecture arch = listToAlts . catMaybes .
 
44
>                             filterAltsByArch arch . altsToList
 
45
>     where listToAlts [] = ""
 
46
>           listToAlts s = join " | " s
 
47
>           altsToList = split '|'
 
48
 
 
49
Here we continue filtering out unwanted architectures.
 
50
filterAltsByArch assumes that the input is in the format used for the
 
51
Build-Depends control file field, with no commas or vertical lines.
 
52
This function is given a list of package-version-architecture clauses,
 
53
and it returns a list.  An element of the return value is either
 
54
Nothing, if the clause was not for this arch, or the clause without
 
55
the arch spec, lifted to Just, if it was for this arch.
 
56
 
 
57
> filterAltsByArch :: String -> [String] -> [Maybe String]
 
58
> filterAltsByArch arch ss = map (checkArch arch . parseAlt) ss
 
59
 
 
60
parseAlt takes a string of the form "package (>> version) [i386 m68k]"
 
61
and parses it into a triplet ("package", ">> version", ["i386",
 
62
"m68k"]).
 
63
 
 
64
> parseAlt :: String -> (String, String, [String])
 
65
> parseAlt s = let (pkg, rest)    = getPkg  . dropWSP $ s
 
66
>                  (vers, rest')  = getVer  . dropWSP $ rest
 
67
>                  (arch, rest'') = getArch . dropWSP $ rest'
 
68
>                  in (pkg, vers, arch)
 
69
 
 
70
dropWSP is what many people call "left strip" or "lstrip": it removes
 
71
all whitespace from the beginning of the string, so that the first
 
72
character of the result is not whitespace.
 
73
 
 
74
> dropWSP :: String -> String
 
75
> dropWSP = dropWhile (`elem` " \t\n")
 
76
 
 
77
getPkg parses "package ..." into ("package", " ..."), returning a pair
 
78
whose left element is the package name and the right element is what
 
79
remains of the string after the parse.
 
80
 
 
81
> getPkg :: String -> (String, String)
 
82
> getPkg = span (\c -> c /= ' ' && c /= '\t')
 
83
 
 
84
getVer parses "(>> version) ..." into (">> version", " ...").  If
 
85
there is no parenthesis at the beginning of the argument, the first
 
86
element of the return pair is empty and the second is the argument in
 
87
full.
 
88
 
 
89
> getVer :: String -> (String, String)
 
90
> getVer ('(':s) = let (f, r) = span (/= ')') s
 
91
>                      in (f, tail r)
 
92
> getVer s@(_:_) = ("", s)
 
93
> getVer "" = ("", "")
 
94
 
 
95
getArch parses an arch spec "[i386 !m68k] ..." into a pair (["i386",
 
96
"!m68k"], " ...") whose first argument is a list of the archs
 
97
mentioned in the spec.  The rest of the string is again returned in
 
98
the second element of the pair.
 
99
 
 
100
> getArch :: String -> ([String], String)
 
101
> getArch ('[':ss) = let (f, r) = span (/= ']') ss
 
102
>                        rv = (filter (not . onlySpace) . split ' ' $ f, tail r)
 
103
>                        in rv
 
104
>               where onlySpace [] = True
 
105
>                     onlySpace (' ':xs)  = onlySpace xs
 
106
>                     onlySpace ('\t':xs) = onlySpace xs
 
107
>                     onlySpace (_:_) = False
 
108
> getArch s@(_:_) = ([], s)
 
109
> getArch "" = ([], "")
 
110
 
 
111
checkArch takes two arguments: the first is a string, containing the
 
112
name of the current architecture; the second is a triplet produced by
 
113
parseAlt.  The result is Nothing, if the pair is not meant for the
 
114
current architecture.  Otherwise the result is Just string, where
 
115
string is a string representation of the triplet without the
 
116
architecture spec.  The logic that determines this is contained in
 
117
four intermediate results:
 
118
 
 
119
   - isInList is true iff current architecture is in the list without
 
120
     a bang
 
121
 
 
122
   - isInListWithBang is true iff current architecture is in the list
 
123
     with a bang
 
124
 
 
125
   - hasbang is true iff there is a bang in the version spec
 
126
 
 
127
   - test is what determines whether the return value is Just or Nothing.
 
128
 
 
129
> checkArch :: String -> (String, String, [String]) -> Maybe String
 
130
> checkArch _ t@(_,_,[]) = Just (stringify t)
 
131
> checkArch arch t@(_,_,a)
 
132
>     = let isInList = arch `elem` a
 
133
>           isInListWithBang = ('!' : arch) `elem` a
 
134
>           hasbang = hasBang a
 
135
>           test = (not isInList && not hasbang) || isInListWithBang
 
136
>           in if test
 
137
>              then Nothing
 
138
>                   else Just (stringify t)
 
139
 
 
140
stringify converts the triplet ("A", "B", ["C", "D"]) into the string
 
141
"A (B)", thereby converting the relationship spec into a string form.
 
142
 
 
143
> stringify :: (String, String, [String]) -> String
 
144
> stringify (p, "", _) = p
 
145
> stringify (p, v, _) = p ++ " (" ++ v ++ ")"
 
146
 
 
147
hasBang returns true if the argument list contains a string 
 
148
that starts with a bang.
 
149
 
 
150
> hasBang :: [String] -> Bool
 
151
> hasBang [] = False
 
152
> hasBang (('!':_):_) = True
 
153
> hasBang ((_:_):ss)  = hasBang ss
 
154
 
 
155
checkArgs tests whether the command line argument list given is in the
 
156
correct format.  If not, we bail out.
 
157
 
 
158
> checkArgs :: [String] -> IO ()
 
159
> checkArgs [] = fail "Too few arguments"
 
160
> checkArgs [x] = return () -- ok
 
161
> checkArgs (_:_:_) = fail "Too many arguments"
 
162
 
 
163
Here's the main program.  We parse arguments, read in the input from
 
164
stdin and then print out the result, which is in the normal Depends
 
165
field format.
 
166
 
 
167
> main = do args <- getArgs
 
168
>           checkArgs args
 
169
>           cont <- getContents
 
170
>           putStrLn . (join ", ") . filter (/= "") .
 
171
>                    map (filterByArchitecture (head args)) .
 
172
>                    lines . bessDeComment $ cont
 
173
 
 
174
 
 
175
 
 
176
split and join are utility functions that really should be in some
 
177
library.  split is a generalization of the standard filter "lines",
 
178
allowing one to specify what is used as the line separator.  join is
 
179
its conceptual inverse.
 
180
 
 
181
> join :: String -> [String] -> String
 
182
> join _ [] = []
 
183
> join _ [s] = s
 
184
> join is (s:ss@(_:_)) = s ++ join' is ss
 
185
>     where join' is = foldl (\a b -> a ++ is ++ b) []
 
186
 
 
187
> split  :: Char -> String -> [String]
 
188
> split _ "" =  []
 
189
> split c s  =  let (l, s') = break (== c) s
 
190
>                   in  l : case s' of
 
191
>                           []      -> []
 
192
>                           (_:s'') -> split c s''
 
193
 
 
194
 
 
195
 
 
196
 
 
197