/[gentoo-src]/portage/pym/portage_config.py
Gentoo

Diff of /portage/pym/portage_config.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.1 Revision 1.1.2.3
1# portage.py -- core Portage functionality
2# Copyright 1998-2003 Gentoo Technologies, Inc. and Authors
3# Authors: Daniel Robbins, Nick Jones, Alain Penders
4# Distributed under the GNU Public License v2
5
6
7from stat import *
8from commands import *
9from select import *
10from output import *
11import string,os,types,sys,shlex,shutil,xpak,fcntl,signal,time,missingos,cPickle,atexit,grp,traceback,commands,pwd
12import portage
13
14
15#-----------------------------------------------------------------------------
16
17
18class config:
19 def __init__(self, ctx):
20 self.ctx = ctx
21
22 self.usesplit=[]
23 self.cexpand={}
24
25 self.usemask=[]
26 self.configlist=[]
27 self.backupenv={}
28 # back up our incremental variables:
29 self.configdict={}
30 # configlist will contain: [ globals, (optional) profile, make.conf, backupenv (incrementals), origenv ]
31
32 #get the masked use flags
33 if os.path.exists("/etc/make.profile/use.mask"):
34 self.usemask=grabfile("/etc/make.profile/use.mask")
35 if os.path.exists("/etc/portage/use.mask"):
36 self.usemask=self.usemask+grabfile("/etc/portage/use.mask")
37
38 self.mygcfg=self.getconfig("/etc/make.globals")
39 if self.mygcfg==None:
40 print "!!! Parse error in /etc/make.globals. NEVER EDIT THIS FILE."
41 print "!!! Incorrect multiline literals can cause this. Do not use them."
42 print "!!! Errors in this file should be reported on bugs.gentoo.org."
43 sys.exit(1)
44 self.configlist.append(self.mygcfg)
45 self.configdict["globals"]=self.configlist[-1]
46
47 # Does /etc/make.profile/make.defaults exist?
48 if self.ctx.get_profiledir():
49 self.mygcfg=self.getconfig("/etc/make.profile/make.defaults")
50 if self.mygcfg==None:
51 print "!!! Parse error in /etc/make.defaults. Never modify this file."
52 print "!!! 'emerge sync' may fix this. If it does not then please report"
53 print "!!! this to bugs.gentoo.org and, if possible, a dev on #gentoo (IRC)"
54 sys.exit(1)
55 self.configlist.append(self.mygcfg)
56 self.configdict["defaults"]=self.configlist[-1]
57
58 self.mygcfg=self.getconfig("/etc/make.conf")
59 if self.mygcfg==None:
60 print "!!! Parse error in /etc/make.conf."
61 print "!!! Incorrect multiline literals can cause this. Do not use them."
62 sys.exit(1)
63 self.configlist.append(self.mygcfg)
64 self.configdict["conf"]=self.configlist[-1]
65
66 for x in self.ctx.get_incrementals():
67 if os.environ.has_key(x):
68 self.backupenv[x]=os.environ[x]
69 #auto-use:
70 self.configlist.append({})
71 self.configdict["auto"]=self.configlist[-1]
72 #backup-env (for recording our calculated incremental variables:)
73 self.configlist.append(self.backupenv)
74 self.configlist.append(os.environ.copy())
75 self.configdict["env"]=self.configlist[-1]
76 self.lookuplist=self.configlist[:]
77 self.lookuplist.reverse()
78
79 useorder=self["USE_ORDER"]
80 if not useorder:
81 #reasonable defaults; this is important as without USE_ORDER, USE will always be "" (nothing set)!
82 useorder="env:conf:auto:defaults"
83 usevaluelist=useorder.split(":")
84 self.uvlist=[]
85 for x in usevaluelist:
86 if self.configdict.has_key(x):
87 #prepend db to list to get correct order
88 self.uvlist[0:0]=[self.configdict[x]]
89 self.regenerate()
90
91 def regenerate(self,useonly=0):
92 if useonly:
93 myincrementals=["USE"]
94 else:
95 myincrementals=self.ctx.get_incrementals()
96 for mykey in myincrementals:
97 if mykey=="USE":
98 mydbs=self.uvlist
99 self.configdict["auto"]["USE"]=self.autouse(self.ctx.db[self.ctx.getRoot()]["vartree"])
100 else:
101 mydbs=self.configlist[:-1]
102 mysetting=[]
103 for curdb in mydbs:
104 if not curdb.has_key(mykey):
105 continue
106 #variables are already expanded
107 mysplit=curdb[mykey].split()
108 for x in mysplit:
109 if x=="-*":
110 # "-*" is a special "minus" var that means "unset all settings". so USE="-* gnome" will have *just* gnome enabled.
111 mysetting=[]
112 continue
113 add=x
114 if x[0]=="-":
115 remove=x[1:]
116 else:
117 remove=x
118 #remove any previous settings of this variable
119 dellist=[]
120 for y in range(0,len(mysetting)):
121 if mysetting[y]==remove:
122 #we found a previously-defined variable; add it to our dellist for later removal.
123 dellist.append(mysetting[y])
124 for y in dellist:
125 while y in mysetting:
126 mysetting.remove(y)
127 #now append our new setting
128 if add:
129 mysetting.append(add)
130 #store setting in last element of configlist, the original environment:
131 self.configlist[-1][mykey]=string.join(mysetting," ")
132 #cache split-up USE var in a global
133 self.usesplit=[]
134 for x in string.split(self.configlist[-1]["USE"]):
135 if x not in self.usemask:
136 self.usesplit.append(x)
137
138 # Pre-Pend ARCH variable to USE settings so '-*' in env doesn't kill arch.
139 if self.ctx.get_profiledir():
140 if self.configdict["defaults"].has_key("ARCH"):
141 if self.configdict["defaults"]["ARCH"]:
142 if self.configdict["defaults"]["ARCH"] not in self.usesplit:
143 self.usesplit.insert(0,self.configdict["defaults"]["ARCH"])
144 self.configlist[-1]["USE"]=string.join(self.usesplit," ")
145
146 def get_usesplit(self):
147 return self.usesplit
148
149 def __getitem__(self,mykey):
150 if mykey=="CONFIG_PROTECT_MASK":
151 suffix=" /etc/env.d"
152 else:
153 suffix=""
154 for x in self.lookuplist:
155 if x == None:
156 print "!!! lookuplist is null."
157 elif x.has_key(mykey):
158 return x[mykey]+suffix
159 return suffix
160
161 def has_key(self,mykey):
162 for x in self.lookuplist:
163 if x.has_key(mykey):
164 return 1
165 return 0
166
167 def keys(self):
168 mykeys=[]
169 for x in self.lookuplist:
170 for y in x.keys():
171 if y not in mykeys:
172 mykeys.append(y)
173 return mykeys
174
175 def __setitem__(self,mykey,myvalue):
176 "set a value; will be thrown away at reset() time"
177 self.configdict["env"][mykey]=myvalue
178
179 def reset(self):
180 "reset environment to original settings"
181 #for x in self.backupenv.keys():
182 # self.configdict["env"][x]==self.backupenv[x]
183 #self.regenerate(useonly=1)
184 pass
185
186 def environ(self):
187 "return our locally-maintained environment"
188 mydict={}
189 for x in self.keys():
190 mydict[x]=self[x]
191 if not mydict.has_key("HOME") and mydict.has_key("BUILD_PREFIX"):
192 print "*** HOME not set. Setting to",mydict["BUILD_PREFIX"]
193 mydict["HOME"]=mydict["BUILD_PREFIX"]
194 return mydict
195
196 def getconfig(self, mycfg, tolerant=0):
197 mykeys={}
198 f=open(mycfg,'r')
199 lex=shlex.shlex(f)
200 lex.wordchars=string.digits+string.letters+"~!@#$%*_\:;?,./-+{}"
201 lex.quotes="\"'"
202 while 1:
203 key=lex.get_token()
204 if (key==''):
205 #normal end of file
206 break;
207 equ=lex.get_token()
208 if (equ==''):
209 #unexpected end of file
210 #lex.error_leader(self.filename,lex.lineno)
211 if not tolerant:
212 print "!!! Unexpected end of config file: variable",key
213 return None
214 else:
215 return mykeys
216 elif (equ!='='):
217 #invalid token
218 #lex.error_leader(self.filename,lex.lineno)
219 if not tolerant:
220 print "!!! Invalid token (not \"=\")",equ
221 return None
222 else:
223 return mykeys
224 val=lex.get_token()
225 if (val==''):
226 #unexpected end of file
227 #lex.error_leader(self.filename,lex.lineno)
228 if not tolerant:
229 print "!!! Unexpected end of config file: variable",key
230 return None
231 else:
232 return mykeys
233 mykeys[key]=self.varexpand(val,mykeys)
234 return mykeys
235
236 def varexpand(self, mystring, mydict={}):
237 try:
238 return self.cexpand[" "+mystring]
239 except KeyError:
240 pass
241 """
242 new variable expansion code. Removes quotes, handles \n, etc.
243 This code is used by the configfile code, as well as others (parser)
244 This would be a good bunch of code to port to C.
245 """
246 numvars=0
247 mystring=" "+mystring
248 #in single, double quotes
249 insing=0
250 indoub=0
251 pos=1
252 newstring=" "
253 while (pos<len(mystring)):
254 if (mystring[pos]=="'") and (mystring[pos-1]!="\\"):
255 if (indoub):
256 newstring=newstring+"'"
257 else:
258 insing=not insing
259 pos=pos+1
260 continue
261 elif (mystring[pos]=='"') and (mystring[pos-1]!="\\"):
262 if (insing):
263 newstring=newstring+'"'
264 else:
265 indoub=not indoub
266 pos=pos+1
267 continue
268 if (not insing):
269 #expansion time
270 if (mystring[pos]=="\n"):
271 #convert newlines to spaces
272 newstring=newstring+" "
273 pos=pos+1
274 elif (mystring[pos]=="\\"):
275 #backslash expansion time
276 if (pos+1>=len(mystring)):
277 newstring=newstring+mystring[pos]
278 break
279 else:
280 a=mystring[pos+1]
281 pos=pos+2
282 if a=='a':
283 newstring=newstring+chr(007)
284 elif a=='b':
285 newstring=newstring+chr(010)
286 elif a=='e':
287 newstring=newstring+chr(033)
288 elif (a=='f') or (a=='n'):
289 newstring=newstring+chr(012)
290 elif a=='r':
291 newstring=newstring+chr(015)
292 elif a=='t':
293 newstring=newstring+chr(011)
294 elif a=='v':
295 newstring=newstring+chr(013)
296 else:
297 #remove backslash only, as bash does: this takes care of \\ and \' and \" as well
298 newstring=newstring+mystring[pos-1:pos]
299 continue
300 elif (mystring[pos]=="$") and (mystring[pos-1]!="\\"):
301 pos=pos+1
302 if (pos+1)>=len(mystring):
303 self.cexpand[mystring]=""
304 return ""
305 if mystring[pos]=="{":
306 pos=pos+1
307 terminus="}"
308 else:
309 terminus=string.whitespace
310 myvstart=pos
311 while mystring[pos] not in terminus:
312 if (pos+1)>=len(mystring):
313 self.cexpand[mystring]=""
314 return ""
315 pos=pos+1
316 myvarname=mystring[myvstart:pos]
317 pos=pos+1
318 if len(myvarname)==0:
319 self.cexpand[mystring]=""
320 return ""
321 numvars=numvars+1
322 if mydict.has_key(myvarname):
323 newstring=newstring+mydict[myvarname]
324 else:
325 newstring=newstring+mystring[pos]
326 pos=pos+1
327 else:
328 newstring=newstring+mystring[pos]
329 pos=pos+1
330 if numvars==0:
331 self.cexpand[mystring]=newstring[1:]
332 return newstring[1:]
333
334 def autouse(self, myvartree):
335 """returns set of USE variables auto-enabled due to packages being installed"""
336 myusevars=""
337 for x in self.ctx.getUseDefaults():
338 mysplit=string.split(x)
339 if len(mysplit)<2:
340 #invalid line
341 continue
342 myuse=mysplit[0]
343 mydep=x[len(mysplit[0]):]
344 #check dependencies; tell depcheck() to ignore settings["USE"] since we are still forming it.
345 myresult=portage.dep_check(mydep,myvartree.dbapi,use="no")
346 if myresult[0]==1 and not myresult[1]:
347 #deps satisfied, add USE variable...
348 myusevars=myusevars+" "+myuse
349 return myusevars
350

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.3

  ViewVC Help
Powered by ViewVC 1.1.20