Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 259318 | Differences between
and this patch

Collapse All | Expand All

(-)/usr/bin/euse (-36 / +434 lines)
Lines 13-18 Link Here
13
MAKE_GLOBALS_PATH=/etc/make.globals
13
MAKE_GLOBALS_PATH=/etc/make.globals
14
MAKE_PROFILE_PATH=/etc/make.profile
14
MAKE_PROFILE_PATH=/etc/make.profile
15
MAKE_CONF_BACKUP_PATH=/etc/make.conf.euse_backup
15
MAKE_CONF_BACKUP_PATH=/etc/make.conf.euse_backup
16
PACKAGE_USE_PATH=/etc/portage/package.use
16
17
17
[ -z "${MODE}" ] && MODE="showhelp"		# available operation modes: showhelp, showversion, showdesc, showflags, modify
18
[ -z "${MODE}" ] && MODE="showhelp"		# available operation modes: showhelp, showversion, showdesc, showflags, modify
18
19
Lines 32-44 Link Here
32
			-E | --enable)         MODE="modify"; ACTION="add";;
33
			-E | --enable)         MODE="modify"; ACTION="add";;
33
			-D | --disable)        MODE="modify"; ACTION="remove";;
34
			-D | --disable)        MODE="modify"; ACTION="remove";;
34
			-P | --prune)          MODE="modify"; ACTION="prune";;
35
			-P | --prune)          MODE="modify"; ACTION="prune";;
36
			-p | --package)	       MODE="modify"; shift; PACKAGE=${1};;
35
			-*)
37
			-*)
36
				echo "ERROR: unknown option ${1} specified."
38
				echo "ERROR: unknown option ${1} specified."
37
				echo
39
				echo
38
				MODE="showhelp"
40
				MODE="showhelp"
39
				;;
41
				;;
40
			"%active")
42
			"%active")
41
				get_useflags
43
				get_portageuseflags
42
				ARGUMENTS="${ARGUMENTS} ${ACTIVE_FLAGS[9]}"
44
				ARGUMENTS="${ARGUMENTS} ${ACTIVE_FLAGS[9]}"
43
				;;
45
				;;
44
			*)
46
			*)
Lines 55-60 Link Here
55
	exit 1
57
	exit 1
56
}
58
}
57
59
60
warn() {
61
	echo "WARNING: ${1}"
62
}
63
58
get_real_path() {
64
get_real_path() {
59
	set -P
65
	set -P
60
	cd "$1"
66
	cd "$1"
Lines 82-87 Link Here
82
	done
88
	done
83
#	[ ! -r "$(get_make_defaults)" ] && error "$(get_make_defaults) is not readable"
89
#	[ ! -r "$(get_make_defaults)" ] && error "$(get_make_defaults) is not readable"
84
	[ "${MODE}" == "modify" -a ! -w "${MAKE_CONF_PATH}" ] && error ""${MAKE_CONF_PATH}" is not writable"
90
	[ "${MODE}" == "modify" -a ! -w "${MAKE_CONF_PATH}" ] && error ""${MAKE_CONF_PATH}" is not writable"
91
	[ "${MODE}" == "modify" -a -s "${PACKAGE_USE_PATH}" -a ! -w "${PACKAGE_USE_PATH}" ] && error ""${PACKAGE_USE_PATH}" is not writable"
85
}
92
}
86
93
87
showhelp() {
94
showhelp() {
Lines 101-113 Link Here
101
         -E, --enable         - enable the given useflags
108
         -E, --enable         - enable the given useflags
102
         -D, --disable        - disable the given useflags
109
         -D, --disable        - disable the given useflags
103
         -P, --prune          - remove all references to the given flags from
110
         -P, --prune          - remove all references to the given flags from
104
                                make.conf to revert to default settings
111
                                make.conf and package.use to revert to default 
112
                                settings
113
         -p, --package        - used with -E, -D, to apply to a specific
114
                                package only
105
115
106
Notes: ${PROGRAM_NAME} currently only works for global flags defined
116
Notes: ${PROGRAM_NAME} currently only works for global flags defined
107
       in make.globals, make.defaults or make.conf, it doesn't handle
117
       in make.globals, make.defaults or make.conf, and local flags defined
108
       use.defaults, use.mask or package.use yet (see portage(5) for details on
118
       in package.use and individual package ebuilds, it doesn't handle
109
       these files). It also might have issues with cascaded profiles.
119
       use.defaults or use.mask yet (see portage(5) for details on these
110
       If multiple options are specified only the last one will be used.
120
       files). It also might have issues with cascaded profiles. If 
121
       multiple options are specified only the last one will be used.
111
HELP
122
HELP
112
}
123
}
113
124
Lines 147-159 Link Here
147
print ' '.join(r)" 
158
print ' '.join(r)" 
148
}
159
}
149
160
161
# Similar to reduce_incrementals except converts lines from package atoms
162
# in /etc/portage/package.use files to lines of "pkg {[-]flag}*"
163
reduce_package_use() {
164
    echo "${@}" | python -c "import sys,re
165
h={}; atom=re.compile(r'[<>]?=?([a-z][\w/-]+[a-z])(-[\dpr._*-]+)?', re.I); 
166
getflags=re.compile(r'(-?[\w*-]+)')
167
for x in sys.stdin.read().split('\n'):
168
	if not x: continue
169
	parts = x.lstrip().split(' ',1)
170
	if len(parts)==1: continue
171
	try:
172
		pkg = atom.match(parts[0]).group(1)
173
	except:
174
		continue
175
	flags = getflags.findall(parts[1])
176
	if not pkg in h: h[pkg]=[]
177
	r=h[pkg]
178
	for x in flags:
179
		if x[0] == '-' and x[1:] in r:
180
			r.remove(x[1:])
181
			r.append(x)
182
		elif x[0] != '-' and '-'+x in r:
183
			r.remove('-'+x)
184
			r.append(x)
185
		elif x == '-*':
186
			r = h[pkg] = ['-*']
187
		elif x not in r:
188
			r.append(x)
189
print '\n'.join([' %s %s ' % (pkg,' '.join(flgs)) for pkg,flgs in h.iteritems() if len(flgs)])"
190
}
191
150
# the following function creates a bash array ACTIVE_FLAGS that contains the
192
# the following function creates a bash array ACTIVE_FLAGS that contains the
151
# global use flags, indexed by origin: 0: environment, 1: make.conf, 
193
# global use flags, indexed by origin: 0: environment, 1: make.conf, 
152
# 2: make.defaults, 3: make.globals
194
# 2: make.defaults, 3: make.globals, 4: package.use, 5: ebuild IUSE
153
get_useflags() {
195
get_useflags() {
154
	# only calculate once as calling emerge is painfully slow
196
	# only calculate once 
155
	[ -n "${USE_FLAGS_CALCULATED}" ] && return
197
	[ -n "${USE_FLAGS_CALCULATED}" ] && return
156
	
198
157
	# backup portdir so get_portdir() doesn't give false results later
199
	# backup portdir so get_portdir() doesn't give false results later
158
	portdir_backup="${PORTDIR}"
200
	portdir_backup="${PORTDIR}"
159
201
Lines 174-183 Link Here
174
	USE="${ACTIVE_FLAGS[0]}"
216
	USE="${ACTIVE_FLAGS[0]}"
175
	PORTDIR="${portdir_backup}"
217
	PORTDIR="${portdir_backup}"
176
218
219
	# Parse through /etc/portage/package.use
220
	if [[ -d ${PACKAGE_USE_PATH} ]]; then
221
		ACTIVE_FLAGS[4]="$( cat ${PACKAGE_USE_PATH}/* \
222
			| sed -re "s/#.*$//" )"
223
	elif [[ -e ${PACKAGE_USE_PATH} ]]; then
224
		ACTIVE_FLAGS[4]="$(sed -re "/#.*$/ d" < ${PACKAGE_USE_PATH})"
225
	fi
226
	# Simplify ACTIVE_FLAGS[4] to be lines of pkg {[-]flag}*
227
	ACTIVE_FLAGS[4]="$(reduce_package_use "${ACTIVE_FLAGS[4]}")"
228
	#
229
	# ACTIVE_FLAGS[5] reserved for USE flags defined in ebuilds and
230
	# is generated/maintained in the get_useflaglist_ebuild() function
231
	#
232
	# Traverse through use.mask and use.force (0.5s)
233
	#ACTIVE_FLAGS[6]=$(reduce_incrementals \
234
	#	$(cat $(traverse_profile "use.mask") \
235
	#		| sed -re "/^#.*$/ {d}"))
236
	#ACTIVE_FLAGS[7]=$(reduce_incrementals \
237
	#	$(cat $(traverse_profile "use.force") \
238
	#		| sed -re "/^#.*$/ {d}"))
239
240
	USE_FLAGS_CALCULATED=1
241
}
242
243
# Fetch USE flags reported active by Portage
244
get_portageuseflags() {
245
	# only calculate once as calling emerge is painfully slow
246
	[ -n "${_PORTAGE_USE_FLAGS_CALCULATED}" ] && return
177
	# get the currently active USE flags as seen by portage, this has to be after
247
	# get the currently active USE flags as seen by portage, this has to be after
178
	# restoring USE or portage won't see the original environment
248
	# restoring USE or portage won't see the original environment
179
	ACTIVE_FLAGS[9]="$(emerge --info | grep 'USE=' | cut -b 5- | sed -e 's:"::g')" #'
249
	ACTIVE_FLAGS[9]="$(emerge --info | grep 'USE=' | cut -b 5- | sed -e 's:"::g')" #'
180
	USE_FLAGS_CALCULATED=1
250
	_PORTAGE_USE_FLAGS_CALCULATED=1
181
}
251
}
182
252
183
# get the list of all known USE flags by reading use.desc and/or use.local.desc
253
# get the list of all known USE flags by reading use.desc and/or use.local.desc
Lines 194-219 Link Here
194
		egrep "^[^# :]+:[^ ]+ +-" "${descdir}/use.local.desc" | cut -d: -f 2 | cut -d\  -f 1
264
		egrep "^[^# :]+:[^ ]+ +-" "${descdir}/use.local.desc" | cut -d: -f 2 | cut -d\  -f 1
195
	fi
265
	fi
196
}
266
}
267
get_useflaglist_ebuild() {
268
	# $1 package atom (app-editor/vim)
269
	# $2 version (7.2)
270
	#
271
	# TODO: Scrap ${2} input. Get a folder listing of the ebuilds,
272
	#		derive version from each file name and create use flag list
273
	#		from each file's contents. Store by package name and
274
	#		version.
275
	#
276
	local known=$(echo "${ACTIVE_FLAGS[5]}" | egrep "^${1};${2}")
277
	if [[ -n $known ]]; then
278
		# Isolate the flags part
279
		echo $known | cut -d\; -f4 | cut -d\" -f2 
280
		return
281
	fi
282
	local pkg=$(echo ${1} | cut -d/ -f2)
283
	# Open the ebuild file and retrieve defined USE flags
284
	[[ ! -d "$(get_portdir)/${1}" ]] && return 1
285
	for file in $(get_portdir)/${1}/*.ebuild; do
286
		# Crazy sed script matches IUSE variable if it spans
287
		# multiple lines
288
		local flags=$(sed -nr -e '/IUSE="/{;:loop;/"$/{;s/\n//g;p;q;};N;b loop;}' ${file})
289
		local slot=$(grep "^SLOT=" ${file})
290
		local version=$(basename ${file} | sed -re "s:${pkg}-(.+)\.ebuild:\1:")
291
		ACTIVE_FLAGS[5]="${ACTIVE_FLAGS[5]}"$'\n'"${1};${version};${slot};${flags}"
292
	done
293
}
197
294
198
# get all make.defaults by traversing the cascaded profile directories
295
# General method of collecting the contents of a profile
199
get_all_make_defaults() {
296
# component by traversing through the cascading profile
297
#
298
# Arguments:
299
# $1 - Filename (make.profile)
300
# [$2] - Current directory (unspecified means to start at the top)
301
traverse_profile() {
200
	local curdir
302
	local curdir
201
	local parent
303
	local parent
202
	local rvalue
304
	local rvalue
203
	
305
	
204
	curdir="${1:-$(get_real_path ${MAKE_PROFILE_PATH})}"
306
	curdir="${2:-$(get_real_path ${MAKE_PROFILE_PATH})}"
205
	
307
	
206
	[ -f "${curdir}/make.defaults" ] && rvalue="${curdir}/make.defaults ${rvalue}"
308
	[ -f "${curdir}/${1}" ] && rvalue="${curdir}/${1} ${rvalue}"
207
	if [ -f "${curdir}/parent" ]; then
309
	if [ -f "${curdir}/parent" ]; then
208
		for parent in $(egrep -v '(^#|^ *$)' ${curdir}/parent); do
310
		for parent in $(egrep -v '(^#|^ *$)' ${curdir}/parent); do
209
			pdir="$(get_real_path ${curdir}/${parent})"
311
			pdir="$(get_real_path ${curdir}/${parent})"
210
			rvalue="$(get_all_make_defaults ${pdir}) ${rvalue}"
312
			rvalue="$(traverse_profile ${1} ${pdir}) ${rvalue}"
211
		done
313
		done
212
	fi
314
	fi
213
315
214
	echo "${rvalue}"
316
	echo "${rvalue}"
215
}
317
}
216
318
319
# get all make.defaults by traversing the cascaded profile directories
320
get_all_make_defaults() {
321
	if [[ -n $MAKE_DEFAULTS ]]; then
322
		echo $MAKE_DEFAULTS
323
		return
324
	fi
325
	traverse_profile "make.defaults"
326
}
327
217
# get the path to make.defaults by traversing the cascaded profile directories
328
# get the path to make.defaults by traversing the cascaded profile directories
218
get_make_defaults() {
329
get_make_defaults() {
219
	local curdir
330
	local curdir
Lines 238-266 Link Here
238
# 3: echo value for positive (and as lowercase for negative) test result, 
349
# 3: echo value for positive (and as lowercase for negative) test result, 
239
# 4 (optional): echo value for "missing" test result, defaults to blank
350
# 4 (optional): echo value for "missing" test result, defaults to blank
240
get_flagstatus_helper() {
351
get_flagstatus_helper() {
241
	if echo " ${ACTIVE_FLAGS[${2}]} " | grep " ${1} " > /dev/null; then
352
	if [[ -z ${flags} ]]; then 
242
		echo -n "${3}"
353
		local flags=${ACTIVE_FLAGS[${2}]}
243
	elif echo " ${ACTIVE_FLAGS[${2}]} " | grep " -${1} " > /dev/null; then
354
	fi
244
		echo -n "$(echo ${3} | tr [[:upper:]] [[:lower:]])"
355
	local flag=$(echo " $flags " | grep -Eo " [+-]?${1} ")
356
	if [[ ${flag:1:1} == "-" ]]; then
357
		echo -e -n "${3}" | tr [:upper:]+ [:lower:]-
358
	elif [[ -n ${flag} ]]; then
359
		echo -e -n "${3}"
245
	else
360
	else
246
		echo -n "${4:- }"
361
		echo -n "${4:- }"
247
	fi
362
	fi
248
}
363
}
364
get_flagstatus_helper_pkg() {
365
	if [[ -z ${flags} ]]; then
366
		local flags=$(echo " ${ACTIVE_FLAGS[${2}]} " | grep "${5} ");
367
	fi
368
	if [[ -z ${5} || -z ${flags} ]]; then
369
		echo -e -n "${4:- }"
370
		return
371
	fi
372
	get_flagstatus_helper "$@"
373
}
374
get_flagstatus_helper_ebuild() {
375
	if [[ -z ${5} ]]; then 
376
		echo -n "${4:- }" 
377
		return
378
	fi
379
	#local info=$( get_useflaglist_ebuild "${5}" "${6}")
380
	local flags=$(echo $2 | cut -d\" -f2) 
381
	local flag=$(echo " $flags " | grep -Eo " [+-]?$1 ")
382
	if [[ ${flag:1:1} == "+" ]]; then
383
		echo -en "${3}"
384
	elif [[ ${flag:1:1} == "-" ]]; then
385
		echo -en "${3}" | tr [:upper:]+ [:lower:]-
386
	elif [[ -z $flag ]]; then
387
		echo -en "!"
388
	else
389
		echo -en "${4:- }"
390
	fi
391
}
249
392
250
# prints a status string for the given flag, each column indicating the presence
393
# prints a status string for the given flag, each column indicating the presence
251
# for portage, in the environment, in make.conf, in make.defaults and in make.globals.
394
# for portage, in the environment, in make.conf, in make.defaults and in make.globals.
252
# full positive value would be "[+ECDG]", full negative value would be [-ecdg],
395
# full positive value would be "[+ECDG]", full negative value would be [-ecdgpb],
253
# full missing value would be "[-    ]" (portage only sees present or not present)
396
# full missing value would be "[-    ]" (portage only sees present or not present)
254
get_flagstatus() {
397
get_flagstatus() {
255
	get_useflags
398
	get_useflags
256
399
257
	echo -n '['
400
	local E=$(get_flagstatus_helper "${1}" 0 "E")
258
	get_flagstatus_helper "${1}" 9 "+" "-"
401
	local C=$(get_flagstatus_helper "${1}" 1 "C")
259
	get_flagstatus_helper "${1}" 0 "E"
402
	local D=$(get_flagstatus_helper "${1}" 2 "D")
260
	get_flagstatus_helper "${1}" 1 "C"
403
	local G=$(get_flagstatus_helper "${1}" 3 "G")
261
	get_flagstatus_helper "${1}" 2 "D"
404
	#
262
	get_flagstatus_helper "${1}" 3 "G"
405
	# Use flag precedence is defined (at least) at:
263
	echo -n '] '
406
	# http://www.gentoo.org/doc/en/handbook/handbook-x86.xml?part=2&chap=2
407
	for location in "E" "C" "D" "G"; do
408
		if [[ ${!location} == $location ]]; then
409
			local ACTIVE="+"
410
			break
411
		elif [[ ${!location} != " " ]]; then 
412
			local ACTIVE="-"
413
			break
414
		fi
415
	done
416
	echo -n "[${ACTIVE:--}$E$C$D$G] "
417
	if [[ $ACTIVE == "+" ]]; then
418
		return 0
419
	else
420
		return 1
421
	fi
422
}
423
424
get_flagstatus_pkg() {
425
	# Arguments:
426
	# $1 - flag (gtk)
427
	# $2 - package atom (www-client/elinks)
428
	# $3 - +/- whether flag is enabled by global configuration files
429
	#
430
	# Pre-cache the use flags declared in ebuilds first.
431
	# This is required as calling it inside a $() seems to
432
	# prevent caching of results into $ACTIVE_FLAGS array
433
	get_useflaglist_ebuild ${2} > /dev/null
434
	#
435
	# Fetch list of package ebuilds matching the query from equery.
436
	# 	Since determining the current version of a package requires
437
	#	scanning for available ones, inpecting the KEYWORDS variable
438
	#	and then checking in a heap of other places for exceptions,
439
	#   equery is a simple alternative
440
	#
441
	echo "${ACTIVE_FLAGS[5]}" | grep $2 | while read pkgline; do
442
		# This is a bit crazy, but faster than calling equery
443
		OIFS=$IFS; IFS=";"; INFO=($pkgline); IFS=$OIFS;
444
		local version=${INFO[1]}
445
		local slot=${INFO[2]}
446
		local iuse=${INFO[3]}
447
		if [[ $slot == 'SLOT="0"' || $slot == "" ]]; then 
448
			slot=""; 
449
		else
450
			slot="($(echo ${slot} | cut -d\" -f2)) "
451
		fi
452
		# 
453
		# Fetch enabled status for this version
454
		local P=$(get_flagstatus_helper_pkg "${1}" 4 "P" "" "${2}" "${version}")
455
		local B=$(get_flagstatus_helper_ebuild "${1}" "${iuse}" "B" "" "${2}" "${version}")
456
		ACTIVE=; UNUSED=
457
		for location in "P" "B"; do
458
			if [[ ${!location} == $location ]]; then
459
				ACTIVE="+"
460
				break
461
			elif [[ ${!location} == "!" ]]; then 
462
				UNUSED=1
463
			elif [[ ${!location} != " " ]]; then 
464
				ACTIVE="-"
465
				break
466
			fi
467
		done
468
		if [[ $UNUSED ]]; then
469
			echo "          -   ${slot}${version}"
470
		else
471
			echo "        [${ACTIVE:-${3:- }}$P$B] ${slot}${version}"
472
		fi
473
	done
474
	echo
264
}
475
}
265
476
266
# faster replacement to `portageq portdir`
477
# faster replacement to `portageq portdir`
Lines 285-290 Link Here
285
	local found_one
496
	local found_one
286
	local args
497
	local args
287
	
498
	
499
	set -f
288
	args="${*:-*}"
500
	args="${*:-*}"
289
	
501
	
290
	if [ -z "${SCOPE}" ]; then
502
	if [ -z "${SCOPE}" ]; then
Lines 299-305 Link Here
299
	[ "${SCOPE}" == "global" ] && echo "global use flags (searching: ${args})"
511
	[ "${SCOPE}" == "global" ] && echo "global use flags (searching: ${args})"
300
	[ "${SCOPE}" == "local" ] && echo "local use flags (searching: ${args})"
512
	[ "${SCOPE}" == "local" ] && echo "local use flags (searching: ${args})"
301
	echo "************************************************************"
513
	echo "************************************************************"
302
	
514
	set +f
303
	if [ "${args}" == "*" ]; then
515
	if [ "${args}" == "*" ]; then
304
		args="$(get_useflaglist | sort -u)"
516
		args="$(get_useflaglist | sort -u)"
305
	fi
517
	fi
Lines 327-335 Link Here
327
					pkg="$(echo $line | cut -d\| -f 1)"
539
					pkg="$(echo $line | cut -d\| -f 1)"
328
					flag="$(echo $line | cut -d\| -f 2)"
540
					flag="$(echo $line | cut -d\| -f 2)"
329
					desc="$(echo $line | cut -d\| -f 3)"
541
					desc="$(echo $line | cut -d\| -f 3)"
330
					get_flagstatus "${flag}"
542
					if get_flagstatus "${flag}"; then
331
					printf "%s (%s):\n%s\n\n" "${flag}" "${pkg}" "${desc}"
543
						ACTIVE="+"
544
					else
545
						ACTIVE="-"
546
					fi
547
					printf "%s\n    %s: %s\n" "${flag}" "${pkg}" "${desc}"
548
					get_flagstatus_pkg "${flag}" "${pkg}" "${ACTIVE}"
332
				done
549
				done
550
				echo
333
		fi
551
		fi
334
		shift
552
		shift
335
	done
553
	done
Lines 351-358 Link Here
351
	args=("${@:-*}")
569
	args=("${@:-*}")
352
570
353
	case "${SCOPE}" in
571
	case "${SCOPE}" in
354
		"global") echo "global use flags (searching: ${args})";;
572
		"global") echo "global use flags (searching: ${args[@]})";;
355
		 "local") echo "local use flags (searching: ${args})";;
573
		 "local") echo "local use flags (searching: ${args[@]})";;
356
		       *) SCOPE="global" showinstdesc "${args[@]}"
574
		       *) SCOPE="global" showinstdesc "${args[@]}"
357
		          echo
575
		          echo
358
		          SCOPE="local" showinstdesc "${args[@]}"
576
		          SCOPE="local" showinstdesc "${args[@]}"
Lines 366-372 Link Here
366
		args="$(get_useflaglist | sort -u)"
584
		args="$(get_useflaglist | sort -u)"
367
	fi
585
	fi
368
	
586
	
369
	set "${args[@]}"
587
	set ${args[@]}
370
	
588
	
371
	while [ -n "${1}" ]; do
589
	while [ -n "${1}" ]; do
372
		case "${SCOPE}" in
590
		case "${SCOPE}" in
Lines 394-403 Link Here
394
					# print name only if package is installed
612
					# print name only if package is installed
395
					# NOTE: If we implement bug #114086 's enhancement we can just use the
613
					# NOTE: If we implement bug #114086 's enhancement we can just use the
396
					#       exit status of equery instead of a subshell and pipe to wc -l
614
					#       exit status of equery instead of a subshell and pipe to wc -l
397
					if [ $(equery -q -C list -i -e "${pkg}" | wc -l) -gt 0 ]; then
615
					if [ $(equery -q -C list -i "${pkg}" | wc -l) -gt 0 ]; then
398
						foundone=1
616
						foundone=1
399
						IFS="$OIFS"
617
						IFS="$OIFS"
400
						get_flagstatus "${flag}"
618
						get_flagstatus "${flag}" "${pkg}"
401
						IFS=': '
619
						IFS=': '
402
						printf "%s (%s):\n%s\n\n" "${flag}" "${pkg}" "${desc#- }"
620
						printf "%s (%s):\n%s\n\n" "${flag}" "${pkg}" "${desc#- }"
403
					fi
621
					fi
Lines 428-438 Link Here
428
	set ${args}
646
	set ${args}
429
	
647
	
430
	while [ -n "${1}" ]; do
648
	while [ -n "${1}" ]; do
649
		get_portageuseflags
431
		if echo " ${ACTIVE_FLAGS[9]} " | grep " ${1} " > /dev/null; then
650
		if echo " ${ACTIVE_FLAGS[9]} " | grep " ${1} " > /dev/null; then
432
			printf "%-20s" ${1}
651
			printf "%-20s" ${1}
433
			get_flagstatus ${1}
652
			get_flagstatus ${1}
434
			echo
653
			echo
435
		fi
654
		fi
655
		if echo " ${ACTIVE_FLAGS[4]} " | egrep -e " -?${1} " > /dev/null; then
656
			for pkg in $( echo "${ACTIVE_FLAGS[4]}" | \
657
					egrep " -?${1} " | cut -d " " -f 2); do
658
				printf "%-20s" ${1}
659
				SCOPE="local" get_flagstatus ${1} "${pkg}"
660
				printf "(%s)\n" ${pkg}
661
			done;
662
		fi
436
		shift
663
		shift
437
	done
664
	done
438
}
665
}
Lines 446-454 Link Here
446
	NEW_MAKE_CONF_USE="${NEW_MAKE_CONF_USE// ${1} / }"
673
	NEW_MAKE_CONF_USE="${NEW_MAKE_CONF_USE// ${1} / }"
447
}
674
}
448
675
676
# Simple utility to remove empty files from package.use
677
clean_package_use() {
678
if [[ -d ${PACKAGE_USE_PATH} ]]; then
679
	for f in $(find ${PACKAGE_USE_PATH} -size 0); do
680
		echo "Removing empty file ""${f}"""
681
		rm ${f}
682
	done;
683
fi
684
}
685
686
# Utility to remove a use flag from a file in package.use[/]
687
# Args: (1) File, (2) Use flag
688
scrub_use_flag() {
689
	local atom_re="^[<>]?=?([a-z][\da-z/-]+[a-z])(-[0-9pr._*-]+)?"
690
	local filename=${1}
691
	# Ignore leading - on flag
692
	local flag=${2#*-}
693
	local pkg=$(echo "${PACKAGE}" | sed -re "s/${atom_re}/\1/")
694
	local pkg_re="[<>]?=?${pkg}(-[\dpr._*-]+)?"
695
696
	while read line; do
697
		# Skip (preserve) comments on their own lines
698
		if [[ -z $(echo "${line}" | sed -re "s/^ *#.*$//") ]]; then
699
			echo "${line}"
700
		# Detect if requested package is defined on this line
701
		elif [[ -n ${PACKAGE} ]]; then
702
			if [[ -n $(echo ${line} | grep -Ee "[^#]*${pkg_re}") ]]; then	
703
				# If this is the only (remaining) use flag defined
704
                # for this package, then remove the whole line
705
                if [[ -z $(echo ${line} | \
706
						grep -Pe "^[^#]*${pkg_re}[ ]*-?${flag}[ ]$") ]]; then
707
					# Remove flag from this line
708
					echo "${line}" | sed -re "s/-?\b${flag}\b//"
709
				fi
710
			else
711
				# Passthru
712
				echo "${line}"
713
			fi
714
		# If line only has this use flag, let it be removed 
715
		# (used if PACKAGE is not defined -- from pruning)
716
		elif [[ -z $(echo ${line} | \
717
				grep -re "[^#]*${atom_re}.*-?${flag}") ]]; then
718
			# Remove flag from this line
719
			echo "${line}" | sed -re "s/-?\b${flag}\b//"
720
		else
721
			# Passthru
722
			echo "${line}"
723
		fi;
724
	done < <(cat "${filename}") > "${filename}";
725
}
726
727
modify_package() {
728
	get_useflags
729
730
	local atom_re="^[<>]?=?([a-z][\da-z/-]+[a-z])(-[0-9pr._*-]+)?"
731
	local pkg=$(echo "${PACKAGE}" | sed -re "s/${atom_re}/\1/")
732
	local pkg_re="[<>]?=?${pkg}(-[\dpr._*-]+)?"
733
734
	while [[ -n ${1} ]]; do
735
	local flag=${1}
736
	#
737
	# --- Sanity checks
738
	# (1) make sure ${pkg} exists in portdir
739
	if [[ ! -d "$(get_portdir)/${pkg}" ]]; then
740
		error "Package ""${pkg}"" does not exist"
741
	#
742
	# (2) make sure ${flag} is defined in get_useflaglist
743
	elif [[ ! -n $(echo " $(get_useflaglist) " | grep "${flag}") ]]; then
744
		warn "USE flag ""${flag}"" does not exist"
745
		# Don't bail just because of this, just warn
746
	fi;
747
	# If flag is enabled in portage USE flags (emerge --info), 
748
	# then "remove"ing the flag should be replaced with adding
749
	# the negative flag instead
750
	if [[ "${ACTION}" == "remove" &&
751
			-z $( echo " ${ACTIVE_FLAGS[4]} " | egrep -e " ${PACKAGE}.*${flag}\b" ) &&
752
			$( get_flagstatus ${flag} ${pkg} | grep "+" ) ]]; then
753
		flag="-${flag}"
754
		ACTION="add"
755
	# If flag is currently disabled for the package requested 
756
	# to be enabled in, then "remove" the negative
757
	elif [[ "${ACTION}" == "add" &&
758
			-n $( echo " ${ACTIVE_FLAGS[4]} " | egrep -e " ${PACKAGE}.*-${flag}\b" ) ]]; then
759
		flag="-${flag}"
760
		ACTION="remove"
761
	fi;
762
	case "${ACTION}" in
763
		"add")
764
			local filename
765
			if [[ -d ${PACKAGE_USE_PATH} ]]; then
766
				# Use naming convention of package.use/package
767
				filename="${PACKAGE_USE_PATH}/${pkg#*/}"
768
				if [[ ! -s "${filename}" ]]; then
769
					# Create new file to contain flag
770
					echo "${PACKAGE} ${flag}" > "${filename}"
771
					echo "Adding ""${PACKAGE}:${flag}"" use flag to new file ""${filename}"""
772
					return
773
				fi;
774
			else	
775
				# Add to package.use file instead
776
				filename=${PACKAGE_USE_PATH}
777
				# Create as necessary
778
				touch "${filename}"
779
			fi;
780
			# Walk through the file and add the flag manually
781
			echo "Adding ""${PACKAGE}:${flag}"" use flag in ""${filename}"""
782
            local added=0
783
			while read line; do
784
				if [[ -n $(echo "${line}" | egrep -e "^[^#]*${pkg_re}") ]]; then
785
					echo "$(reduce_package_use "${line} ${flag}" | cut -d " " -f 2-)"
786
					added=1
787
				else
788
					# Passthru
789
					echo "${line}"
790
				fi;
791
			done < <(cat "${filename}") > ${filename}
792
			if [[ ${added} == 0 ]]; then
793
				echo "${PACKAGE} ${flag}" >> "${filename}"
794
			fi
795
			;;
796
		"remove")
797
			local filename
798
			if [[ -d ${PACKAGE_USE_PATH} ]]; then
799
				# Scan for file containing named package and use flag
800
				filename=$( egrep -rle "${pkg_re}.*[^-]${flag}( |$)" "${PACKAGE_USE_PATH}")
801
				if [[ -z "${filename}" ]]; then
802
					error ""${flag}" is not defined for package "${PACKAGE}""
803
					return
804
				fi;
805
			else
806
				# Remove from package.use instead
807
				filename=${PACKAGE_USE_PATH}
808
				# Create as necessary
809
				touch "${filename}"
810
			fi;
811
			# Scrub use flag from matched files
812
			for f in ${filename}; do
813
				# Remove current flags in file
814
				echo "Removing ""${PACKAGE}:${flag}"" use flag in ""${f}"""
815
				scrub_use_flag ${f} ${flag}
816
			done;
817
			# Remove empty files
818
			clean_package_use
819
			;;
820
	esac;
821
	shift;
822
	done;
823
}
824
449
# USE flag modification function. Mainly a loop with calls to add_flag and 
825
# USE flag modification function. Mainly a loop with calls to add_flag and 
450
# remove_flag to create a new USE string which is then inserted into make.conf.
826
# remove_flag to create a new USE string which is then inserted into make.conf.
451
modify() {
827
modify() {
828
	if [[ -n ${PACKAGE} ]]; then
829
		modify_package ${*}
830
		return;
831
	fi;
832
452
	if [ -z "${*}" ]; then
833
	if [ -z "${*}" ]; then
453
		if [ "${ACTION}" != "prune" ]; then
834
		if [ "${ACTION}" != "prune" ]; then
454
			echo "WARNING: no USE flags listed for modification, do you really"
835
			echo "WARNING: no USE flags listed for modification, do you really"
Lines 488-493 Link Here
488
			elif echo " ${NEW_MAKE_CONF_USE} " | grep " -${1} " > /dev/null; then
869
			elif echo " ${NEW_MAKE_CONF_USE} " | grep " -${1} " > /dev/null; then
489
				remove_flag "-${1}"
870
				remove_flag "-${1}"
490
			fi
871
			fi
872
			# Locate use flag in package.use
873
			local filename
874
			if [[ -d ${PACKAGE_USE_PATH} ]]; then
875
				filename=$( egrep -rle "-?\b${1}\b" "${PACKAGE_USE_PATH}")
876
			else
877
				# Scrub from package.use file
878
				filename=${PACKAGE_USE_PATH}
879
			fi
880
			# Scrub use flag from matched files
881
			for f in ${filename}; do
882
				# Remove current flags in file
883
				echo "Disabling ""${1}"" use flag in ""${f}"""
884
				scrub_use_flag ${f} ${1} 
885
			done;
886
			# Remove empty files from package.use
887
			clean_package_use
491
			shift
888
			shift
492
		fi
889
		fi
493
	done
890
	done
Lines 545-550 Link Here
545
set -f
942
set -f
546
parse_arguments "$@"
943
parse_arguments "$@"
547
check_sanity
944
check_sanity
945
set +f
548
946
549
eval ${MODE} ${ARGUMENTS}
947
eval ${MODE} ${ARGUMENTS}
550
set +f
948

Return to bug 259318