/[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.5
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.configdict["env"]["PORTAGE_GID"]=str(self.ctx.get_portage_gid())
90 self.regenerate()
91
92 def regenerate(self,useonly=0):
93 if useonly:
94 myincrementals=["USE"]
95 else:
96 myincrementals=self.ctx.get_incrementals()
97 for mykey in myincrementals:
98 if mykey=="USE":
99 mydbs=self.uvlist
100 self.configdict["auto"]["USE"]=self.autouse(self.ctx.db[self.ctx.getRoot()]["vartree"])
101 else:
102 mydbs=self.configlist[:-1]
103 mysetting=[]
104 for curdb in mydbs:
105 if not curdb.has_key(mykey):
106 continue
107 #variables are already expanded
108 mysplit=curdb[mykey].split()
109 for x in mysplit:
110 if x=="-*":
111 # "-*" is a special "minus" var that means "unset all settings". so USE="-* gnome" will have *just* gnome enabled.
112 mysetting=[]
113 continue
114 add=x
115 if x[0]=="-":
116 remove=x[1:]
117 else:
118 remove=x
119 #remove any previous settings of this variable
120 dellist=[]
121 for y in range(0,len(mysetting)):
122 if mysetting[y]==remove:
123 #we found a previously-defined variable; add it to our dellist for later removal.
124 dellist.append(mysetting[y])
125 for y in dellist:
126 while y in mysetting:
127 mysetting.remove(y)
128 #now append our new setting
129 if add:
130 mysetting.append(add)
131 #store setting in last element of configlist, the original environment:
132 self.configlist[-1][mykey]=string.join(mysetting," ")
133 #cache split-up USE var in a global
134 self.usesplit=[]
135 for x in string.split(self.configlist[-1]["USE"]):
136 if x not in self.usemask:
137 self.usesplit.append(x)
138
139 # Pre-Pend ARCH variable to USE settings so '-*' in env doesn't kill arch.
140 if self.ctx.get_profiledir():
141 if self.configdict["defaults"].has_key("ARCH"):
142 if self.configdict["defaults"]["ARCH"]:
143 if self.configdict["defaults"]["ARCH"] not in self.usesplit:
144 self.usesplit.insert(0,self.configdict["defaults"]["ARCH"])
145 self.configlist[-1]["USE"]=string.join(self.usesplit," ")
146
147 def get_usesplit(self):
148 return self.usesplit
149
150 def __getitem__(self,mykey):
151 if mykey=="CONFIG_PROTECT_MASK":
152 suffix=" /etc/env.d"
153 else:
154 suffix=""
155 for x in self.lookuplist:
156 if x == None:
157 print "!!! lookuplist is null."
158 elif x.has_key(mykey):
159 return x[mykey]+suffix
160 return suffix
161
162 def has_key(self,mykey):
163 for x in self.lookuplist:
164 if x.has_key(mykey):
165 return 1
166 return 0
167
168 def keys(self):
169 mykeys=[]
170 for x in self.lookuplist:
171 for y in x.keys():
172 if y not in mykeys:
173 mykeys.append(y)
174 return mykeys
175
176 def __setitem__(self,mykey,myvalue):
177 "set a value; will be thrown away at reset() time"
178 self.configdict["env"][mykey]=myvalue
179
180 def reset(self):
181 "reset environment to original settings"
182 #for x in self.backupenv.keys():
183 # self.configdict["env"][x]==self.backupenv[x]
184 #self.regenerate(useonly=1)
185 pass
186
187 def environ(self):
188 "return our locally-maintained environment"
189 mydict={}
190 for x in self.keys():
191 mydict[x]=self[x]
192 if not mydict.has_key("HOME") and mydict.has_key("BUILD_PREFIX"):
193 print "*** HOME not set. Setting to",mydict["BUILD_PREFIX"]
194 mydict["HOME"]=mydict["BUILD_PREFIX"]
195 return mydict
196
197 def getconfig(self, mycfg, tolerant=0):
198 mykeys={}
199 f=open(mycfg,'r')
200 lex=shlex.shlex(f)
201 lex.wordchars=string.digits+string.letters+"~!@#$%*_\:;?,./-+{}"
202 lex.quotes="\"'"
203 while 1:
204 key=lex.get_token()
205 if (key==''):
206 #normal end of file
207 break;
208 equ=lex.get_token()
209 if (equ==''):
210 #unexpected end of file
211 #lex.error_leader(self.filename,lex.lineno)
212 if not tolerant:
213 print "!!! Unexpected end of config file: variable",key
214 return None
215 else:
216 return mykeys
217 elif (equ!='='):
218 #invalid token
219 #lex.error_leader(self.filename,lex.lineno)
220 if not tolerant:
221 print "!!! Invalid token (not \"=\")",equ
222 return None
223 else:
224 return mykeys
225 val=lex.get_token()
226 if (val==''):
227 #unexpected end of file
228 #lex.error_leader(self.filename,lex.lineno)
229 if not tolerant:
230 print "!!! Unexpected end of config file: variable",key
231 return None
232 else:
233 return mykeys
234 mykeys[key]=self.varexpand(val,mykeys)
235 return mykeys
236
237 def varexpand(self, mystring, mydict={}):
238 try:
239 return self.cexpand[" "+mystring]
240 except KeyError:
241 pass
242 """
243 new variable expansion code. Removes quotes, handles \n, etc.
244 This code is used by the configfile code, as well as others (parser)
245 This would be a good bunch of code to port to C.
246 """
247 numvars=0
248 mystring=" "+mystring
249 #in single, double quotes
250 insing=0
251 indoub=0
252 pos=1
253 newstring=" "
254 while (pos<len(mystring)):
255 if (mystring[pos]=="'") and (mystring[pos-1]!="\\"):
256 if (indoub):
257 newstring=newstring+"'"
258 else:
259 insing=not insing
260 pos=pos+1
261 continue
262 elif (mystring[pos]=='"') and (mystring[pos-1]!="\\"):
263 if (insing):
264 newstring=newstring+'"'
265 else:
266 indoub=not indoub
267 pos=pos+1
268 continue
269 if (not insing):
270 #expansion time
271 if (mystring[pos]=="\n"):
272 #convert newlines to spaces
273 newstring=newstring+" "
274 pos=pos+1
275 elif (mystring[pos]=="\\"):
276 #backslash expansion time
277 if (pos+1>=len(mystring)):
278 newstring=newstring+mystring[pos]
279 break
280 else:
281 a=mystring[pos+1]
282 pos=pos+2
283 if a=='a':
284 newstring=newstring+chr(007)
285 elif a=='b':
286 newstring=newstring+chr(010)
287 elif a=='e':
288 newstring=newstring+chr(033)
289 elif (a=='f') or (a=='n'):
290 newstring=newstring+chr(012)
291 elif a=='r':
292 newstring=newstring+chr(015)
293 elif a=='t':
294 newstring=newstring+chr(011)
295 elif a=='v':
296 newstring=newstring+chr(013)
297 else:
298 #remove backslash only, as bash does: this takes care of \\ and \' and \" as well
299 newstring=newstring+mystring[pos-1:pos]
300 continue
301 elif (mystring[pos]=="$") and (mystring[pos-1]!="\\"):
302 pos=pos+1
303 if (pos+1)>=len(mystring):
304 self.cexpand[mystring]=""
305 return ""
306 if mystring[pos]=="{":
307 pos=pos+1
308 terminus="}"
309 else:
310 terminus=string.whitespace
311 myvstart=pos
312 while mystring[pos] not in terminus:
313 if (pos+1)>=len(mystring):
314 self.cexpand[mystring]=""
315 return ""
316 pos=pos+1
317 myvarname=mystring[myvstart:pos]
318 pos=pos+1
319 if len(myvarname)==0:
320 self.cexpand[mystring]=""
321 return ""
322 numvars=numvars+1
323 if mydict.has_key(myvarname):
324 newstring=newstring+mydict[myvarname]
325 else:
326 newstring=newstring+mystring[pos]
327 pos=pos+1
328 else:
329 newstring=newstring+mystring[pos]
330 pos=pos+1
331 if numvars==0:
332 self.cexpand[mystring]=newstring[1:]
333 return newstring[1:]
334
335 def autouse(self, myvartree):
336 """returns set of USE variables auto-enabled due to packages being installed"""
337 myusevars=""
338 for x in self.ctx.getUseDefaults():
339 mysplit=string.split(x)
340 if len(mysplit)<2:
341 #invalid line
342 continue
343 myuse=mysplit[0]
344 mydep=x[len(mysplit[0]):]
345 #check dependencies; tell depcheck() to ignore settings["USE"] since we are still forming it.
346 myresult=portage.dep_check(self.ctx, mydep,myvartree.dbapi,use="no")
347 if myresult[0]==1 and not myresult[1]:
348 #deps satisfied, add USE variable...
349 myusevars=myusevars+" "+myuse
350 return myusevars
351

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

  ViewVC Help
Powered by ViewVC 1.1.20