/[gentoo-src]/rc-scripts/src/awk/gendepends.awk
Gentoo

Contents of /rc-scripts/src/awk/gendepends.awk

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.26 - (show annotations) (download)
Thu Mar 10 17:00:04 2005 UTC (15 years, 3 months ago) by azarah
Branch: MAIN
CVS Tags: HEAD
Changes since 1.25: +2 -2 lines
The system() stuff in *depends.awk should be dosystem().

1 # Copyright 1999-2004 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Header: /var/cvsroot/gentoo-src/rc-scripts/src/awk/gendepends.awk,v 1.25 2005/02/23 17:47:43 azarah Exp $
4
5 # bool check_service(name)
6 #
7 # Returns true if the service exists
8 #
9 function check_service(name, x)
10 {
11 for (x = 1; x <= RC_NUMBER; x++) {
12 if (DEPTREE[x,NAME] == name)
13 return 1
14 }
15
16 return 0
17 }
18
19 # int get_service_index(name)
20 #
21 # Return the index position in DEPTREE
22 #
23 function get_service_index(name, x)
24 {
25 for (x = 1; x <= RC_NUMBER; x++) {
26 if (DEPTREE[x,NAME] == name)
27 return x
28 }
29
30 return 0
31 }
32
33 # bool check_depend(service1, type, service2)
34 #
35 # Returns true if 'service1' need/use/is_before/is_after 'service2'
36 #
37 function check_depend(service1, type, service2, tmpsplit, x)
38 {
39 if (check_service(service1)) {
40 x = get_service_index(service1)
41
42 if ((x,type) in DEPTREE) {
43 split(DEPTREE[x,type], tmpsplit)
44
45 for (x in tmpsplit) {
46 if (tmpsplit[x] == service2)
47 return 1
48 }
49 }
50 }
51
52 return 0
53 }
54
55 # bool add_deptree_item(rcnumber, type, item)
56 #
57 # Add an item(s) 'item' to the DEPTREE array at index [rcnumber,type]
58 #
59 function add_deptree_item(rcnumber, type, item)
60 {
61 if (DEPTREE[rcnumber,type] != "")
62 DEPTREE[rcnumber,type] = DEPTREE[rcnumber,type] " " item
63 else
64 DEPTREE[rcnumber,type] = item
65
66 return 1
67 }
68
69 # bool add_provide(service, provide)
70 #
71 # Add a name of a virtual service ('provide') that 'service' Provides
72 #
73 function add_provide(service, provide)
74 {
75 # We cannot have a service Provide a virtual service with the same name as
76 # an existing service ...
77 if (check_service(provide)) {
78 eerror(" Cannot add provide '" provide "', as a service with the same name exists!")
79 return 0
80 }
81
82 if (check_provide(provide)) {
83 # We cannot have more than one service Providing a virtual ...
84 ewarn(" Service '" get_provide(provide) "' already provided by '" provide "'!;")
85 ewarn(" Not adding service '" service "'...")
86 # Do not fail here as we do have a service that resolves the virtual
87 } else {
88 # Sanity check
89 if (check_service(service)) {
90 PROVIDE_LIST[provide] = service
91 } else {
92 eerror(" Cannot add provide '" provide "', as service '" service "' does not exist!")
93 return 0
94 }
95 }
96
97 return 1
98 }
99
100 # string get_provide(provide)
101 #
102 # Return the name of the service that Provides 'provide'
103 #
104 function get_provide(provide)
105 {
106 if (provide in PROVIDE_LIST)
107 if (check_service(PROVIDE_LIST[provide]))
108 return PROVIDE_LIST[provide]
109
110 return ""
111 }
112
113 # bool check_provide(provide)
114 #
115 # Return true if any service Provides the virtual service with name 'provide'
116 #
117 function check_provide(provide)
118 {
119 if (provide in PROVIDE_LIST)
120 return 1
121
122 return 0
123 }
124
125 # bool add_parallel(service, parallel)
126 #
127 # Add 'yes' or 'no' to the parallel modifier of 'service'.
128 #
129 function add_parallel(service, parallel, sindex)
130 {
131 if ((parallel != "yes") && (parallel != "no")) {
132 eerror(" The 'parallel' modifier can only take 'yes' or 'no' as argument!")
133 eerror(" Please fix this in the '" service "' service.")
134 return 0
135 }
136
137 if (check_service(service)) {
138 sindex = get_service_index(service)
139
140 RESOLVED_DEPTREE[sindex,PARALLEL] = parallel
141
142 return 1
143 } else
144 eerror(" Service '" service "' do not exist!")
145
146 return 0
147 }
148
149 # bool add_db_entry(service, type, item)
150 #
151 # Add a entry to RESOLVED_DEPTREE
152 #
153 function add_db_entry(service, type, item, x, sindex, tmpsplit)
154 {
155 if (!check_service(service)) {
156 eerror(" Service '" service "' do not exist!")
157 return 0
158 }
159
160 sindex = get_service_index(service)
161
162 if ((sindex,type) in RESOLVED_DEPTREE) {
163 split(RESOLVED_DEPTREE[sindex,type], tmpsplit)
164
165 for (x in tmpsplit) {
166 if (tmpsplit[x] == item)
167 return 1
168 }
169
170 RESOLVED_DEPTREE[sindex,type] = RESOLVED_DEPTREE[sindex,type] " " item
171 } else {
172 RESOLVED_DEPTREE[sindex,type] = item
173 }
174
175 return 1
176 }
177
178 # void resolve_depend(type, service, deplist)
179 #
180 # Verify a depend entry(s) 'deplist' for service 'service' of type 'type',
181 # and then add it to the DB.
182 #
183 function resolve_depend(type, service, deplist, x, deparray)
184 {
185 if ((type == "") || (service == "") || (deplist == ""))
186 return
187
188 # If there are no existing service 'service', resolve possible
189 # provided services
190 if (!check_service(service)) {
191 if (check_provide(service))
192 service = get_provide(service)
193 else
194 return
195 }
196
197 split(deplist, deparray)
198
199 for (x in deparray) {
200
201 # If there are no existing service 'deparray[x]', resolve possible
202 # provided services
203 if (!check_service(deparray[x])) {
204 if (check_provide(deparray[x]))
205 deparray[x] = get_provide(deparray[x])
206 }
207
208 # Handle 'need', as it is the only dependency type that
209 # should handle invalid database entries currently.
210 if (!check_service(deparray[x])) {
211
212 if (((type == NEED) || (type == NEEDME)) && (deparray[x] != "net")) {
213
214 ewarn(" Can't find service '" deparray[x] "' needed by '" service "'; continuing...")
215
216 # service is broken due to missing 'need' dependencies
217 add_db_entry(service, BROKEN, deparray[x])
218
219 continue
220 }
221 else if (deparray[x] != "net")
222 continue
223 }
224
225 # Ugly bug ... if a service depends on itself, it creates
226 # a 'mini fork bomb' effect, and breaks things...
227 if (deparray[x] == service) {
228
229 # Dont work too well with the '*' use and need
230 if ((type != BEFORE) && (type != AFTER))
231 ewarn(" Service '" deparray[x] "' can't depend on itself; continuing...")
232
233 continue
234 }
235
236 # Currently only these depend/order types are supported
237 if ((type == NEED) || (type == USE) || (type == BEFORE) || (type == AFTER)) {
238
239 if (type == BEFORE) {
240 # NEED and USE override BEFORE (service BEFORE deparray[x])
241 if (check_depend(service, NEED, deparray[x]) ||
242 check_depend(service, USE, deparray[x]))
243 continue
244 }
245
246 if (type == AFTER) {
247 # NEED and USE override AFTER (service AFTER deparray[x])
248 if (check_depend(deparray[x], NEED, service) ||
249 check_depend(deparray[x], USE, service))
250 continue
251 }
252
253 # NEED override USE (service USE deparray[x])
254 if ((type == USE) && (check_depend(deparray[x], NEED, service))) {
255 ewarn(" Service '" deparray[x] "' NEED service '" service "', but service '" service "' wants")
256 ewarn(" to USE service '" deparray[x] "'!")
257 continue
258 }
259
260 # We do not want to add circular depends ...
261 if (check_depend(deparray[x], type, service)) {
262
263 if ((service,deparray[x],type) in CIRCULAR_DEPEND)
264 continue
265
266 if ((deparray[x],service,type) in CIRCULAR_DEPEND)
267 continue
268
269 ewarn(" Services '" service "' and '" deparray[x] "' have circular")
270 ewarn(" dependency of type '" TYPE_NAMES[type] "'; continuing...")
271
272 CIRCULAR_DEPEND[service,deparray[x],type] = "yes"
273
274 continue
275 }
276
277 add_db_entry(service, type, deparray[x])
278
279 # Reverse mapping
280 if (type == NEED)
281 add_db_entry(deparray[x], NEEDME, service)
282
283 # Reverse mapping
284 if (type == USE)
285 add_db_entry(deparray[x], USEME, service)
286
287 # Reverse mapping
288 if (type == BEFORE)
289 add_db_entry(deparray[x], AFTER, service)
290
291 # Reverse mapping
292 if (type == AFTER)
293 add_db_entry(deparray[x], BEFORE, service)
294 }
295 }
296 }
297
298 BEGIN {
299 NAME = 1
300 RC_NUMBER = 0
301
302 # Types ...
303 NEED = 2
304 NEEDME = 3
305 USE = 4
306 USEME = 5
307 BEFORE = 6
308 AFTER = 7
309 BROKEN = 8
310 PARALLEL = 9
311 MTIME = 10
312 PROVIDE = 11 # Not part of Types as when finally printed ...
313 TYPES_MIN = 2
314 TYPES_MAX = 10
315
316 TYPE_NAMES[NEED] = "ineed"
317 TYPE_NAMES[NEEDME] = "needsme"
318 TYPE_NAMES[USE] = "iuse"
319 TYPE_NAMES[USEME] = "usesme"
320 TYPE_NAMES[BEFORE] = "ibefore"
321 TYPE_NAMES[AFTER] = "iafter"
322 TYPE_NAMES[BROKEN] = "broken"
323 TYPE_NAMES[PROVIDE] = "provide"
324 TYPE_NAMES[PARALLEL] = "parallel"
325 TYPE_NAMES[MTIME] = "mtime"
326
327 # Get our environment variables
328 SVCDIR = ENVIRON["SVCDIR"]
329 if (SVCDIR == "") {
330 eerror("Could not get SVCDIR!")
331 exit 1
332 }
333
334 # There we do not really use yet
335 DEPTYPES = ENVIRON["DEPTYPES"]
336 ORDTYPES = ENVIRON["ORDTYPES"]
337
338 #CACHEDTREE = SVCDIR "/deptree"
339 ORIGCACHEDTREE = SVCDIR "/deptree"
340
341 # Since this could be called more than once simultaneously, use a
342 # temporary cache and rename when finished. See bug 48303
343 ("/bin/mktemp "SVCDIR"/treecache.XXXXXXX") | getline CACHEDTREE
344 if (CACHEDTREE == "") {
345 eerror("Failed to create temporary cache!")
346 exit 1
347 }
348
349 # We remove it below now only before moving the temp one over.
350 #assert(dosystem("rm -f " CACHEDTREE ), "system(rm -f " CACHEDTREE ")")
351 }
352
353 {
354 #
355 # Build our DEPTREE array
356 #
357
358 if ($1 == "RCSCRIPT") {
359 RC_NUMBER++
360
361 DEPTREE[RC_NUMBER,NAME] = $2
362 }
363
364 if ($1 == "NEED") {
365 sub(/NEED[[:space:]]*/, "")
366
367 if ($0 != "")
368 add_deptree_item(RC_NUMBER, NEED, $0)
369 }
370
371 if ($1 == "USE") {
372 sub(/USE[[:space:]]*/, "")
373
374 if ($0 != "")
375 add_deptree_item(RC_NUMBER, USE, $0)
376 }
377
378 if ($1 == "BEFORE") {
379 sub(/BEFORE[[:space:]]*/, "")
380
381 if ($0 != "")
382 add_deptree_item(RC_NUMBER, BEFORE, $0)
383 }
384
385 if ($1 == "AFTER") {
386 sub(/AFTER[[:space:]]*/, "")
387
388 if ($0 != "")
389 add_deptree_item(RC_NUMBER, AFTER, $0)
390 }
391
392 if ($1 == "PROVIDE") {
393 sub(/PROVIDE[[:space:]]*/, "")
394
395 if ($0 != "")
396 add_deptree_item(RC_NUMBER, PROVIDE, $0)
397 }
398
399 if ($1 == "PARALLEL") {
400 sub(/PARALLEL[[:space:]]*/, "")
401
402 if ($0 != "")
403 add_deptree_item(RC_NUMBER, PARALLEL, $0)
404 }
405
406 if ($1 == "MTIME") {
407 sub(/MTIME[[:space:]]*/, "")
408
409 if ($0 != "") {
410 # We add this directly to RESOLVED_DEPTREE
411 add_db_entry(DEPTREE[RC_NUMBER,NAME], MTIME, $0)
412 }
413 }
414 }
415
416 END {
417 # Add the 'net' service if it do not exist ...
418 if (!check_service("net")) {
419 RC_NUMBER++
420 DEPTREE[RC_NUMBER,NAME] = "net"
421 }
422
423 # Calculate all the provides and parallels ...
424 for (x = 1;x <= RC_NUMBER;x++) {
425
426 if ((x,PROVIDE) in DEPTREE)
427 add_provide(DEPTREE[x,NAME], DEPTREE[x,PROVIDE])
428
429 if ((x,PARALLEL) in DEPTREE)
430 add_parallel(DEPTREE[x,NAME], DEPTREE[x,PARALLEL])
431 }
432
433 # Now do NEED, USE, BEFORE and AFTER
434 for (x = 1;x <= RC_NUMBER;x++) {
435
436 if ((x,NEED) in DEPTREE)
437 resolve_depend(NEED, DEPTREE[x,NAME], DEPTREE[x,NEED])
438
439 if ((x,USE) in DEPTREE)
440 resolve_depend(USE, DEPTREE[x,NAME], DEPTREE[x,USE])
441
442 if ((x,BEFORE) in DEPTREE)
443 resolve_depend(BEFORE, DEPTREE[x,NAME], DEPTREE[x,BEFORE])
444
445 if ((x,AFTER) in DEPTREE)
446 resolve_depend(AFTER, DEPTREE[x,NAME], DEPTREE[x,AFTER])
447 }
448
449 for (x = TYPES_MIN; x <= TYPES_MAX; x++)
450 print "rc_type_" TYPE_NAMES[x] "=" x >> (CACHEDTREE)
451 print "rc_index_scale=" (TYPES_MAX + 1) >> (CACHEDTREE)
452 print "" >> (CACHEDTREE)
453 print "declare -a RC_DEPEND_TREE" >> (CACHEDTREE)
454 print "" >> (CACHEDTREE)
455 print "RC_DEPEND_TREE[0]=" RC_NUMBER >> (CACHEDTREE)
456 print "" >> (CACHEDTREE)
457
458 # Generate the resolved CACHEDTREE
459 #
460 # NOTE: We used to use depinfo_<scriptname>() function to resolve our
461 # rc_<type> variables, but that do not scale when the names of
462 # the scripts include invalid bash variable characters (+,.,etc).
463 #
464 for (x = 1;x <= RC_NUMBER;x++) {
465
466 print "RC_DEPEND_TREE[" (x * (TYPES_MAX + 1)) "]=\"" DEPTREE[x,NAME] "\"" >> (CACHEDTREE)
467
468 for (y = TYPES_MIN; y <= TYPES_MAX; y++) {
469
470 tmpname = "RC_DEPEND_TREE[" (x * (TYPES_MAX + 1)) "+" y "]"
471
472 if ((x,y) in RESOLVED_DEPTREE) {
473
474 split(RESOLVED_DEPTREE[x,y], tmparray1)
475 count = asort(tmparray1, tmparray2)
476 tmpstr = tmparray2[1]
477
478 for (i = 2;i <= count;i++)
479 tmpstr = tmpstr " " tmparray2[i]
480
481 print tmpname "=\"" tmpstr "\"" >> (CACHEDTREE)
482 } else
483 print tmpname "=" >> (CACHEDTREE)
484 }
485
486 print "" >> (CACHEDTREE)
487 }
488
489 # Do not export these, as we want them local
490 print "RC_GOT_DEPTREE_INFO=\"yes\"" >> (CACHEDTREE)
491 print "" >> (CACHEDTREE)
492
493 if (check_provide("logger"))
494 print "LOGGER_SERVICE=\"" get_provide("logger") "\"" >> (CACHEDTREE)
495 else
496 print "LOGGER_SERVICE=" >> (CACHEDTREE)
497
498 close(CACHEDTREE)
499
500 assert(dosystem("rm -f "ORIGCACHEDTREE), "system(rm -f "ORIGCACHEDTREE")")
501 assert(dosystem("mv "CACHEDTREE" "ORIGCACHEDTREE), "system(mv "CACHEDTREE" "ORIGCACHEDTREE")")
502 }
503
504
505 # vim:ts=4

  ViewVC Help
Powered by ViewVC 1.1.20