[csw-devel] SF.net SVN: gar:[9128] csw/mgar/gar/v2-git

wahwah at users.sourceforge.net wahwah at users.sourceforge.net
Sat Mar 13 10:55:32 CET 2010


Revision: 9128
          http://gar.svn.sourceforge.net/gar/?rev=9128&view=rev
Author:   wahwah
Date:     2010-03-13 09:55:32 +0000 (Sat, 13 Mar 2010)

Log Message:
-----------
mGAR v2-git: Merging changes from v2.

Modified Paths:
--------------
    csw/mgar/gar/v2-git/bin/analyze_module_results.py
    csw/mgar/gar/v2-git/bin/checkpkg
    csw/mgar/gar/v2-git/bin/checkpkg_collect_stats.py
    csw/mgar/gar/v2-git/bin/update_contents_cache.py
    csw/mgar/gar/v2-git/categories/gnome/category.mk
    csw/mgar/gar/v2-git/categories/python/category.mk
    csw/mgar/gar/v2-git/gar.conf.mk
    csw/mgar/gar/v2-git/gar.lib.mk
    csw/mgar/gar/v2-git/gar.mk
    csw/mgar/gar/v2-git/gar.pkg.mk
    csw/mgar/gar/v2-git/lib/python/checkpkg.py
    csw/mgar/gar/v2-git/lib/python/checkpkg_test.py
    csw/mgar/gar/v2-git/lib/python/opencsw.py
    csw/mgar/gar/v2-git/lib/python/opencsw_test.py
    csw/mgar/gar/v2-git/lib/python/package_checks.py
    csw/mgar/gar/v2-git/lib/python/package_checks_test.py
    csw/mgar/gar/v2-git/lib/python/submit_to_newpkgs.py
    csw/mgar/gar/v2-git/tests/run_tests.py

Added Paths:
-----------
    csw/mgar/gar/v2-git/lib/checkpkg.d/
    csw/mgar/gar/v2-git/lib/checkpkg.d/README
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-actionclasses.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-archall.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-auto.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-basic.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-libs.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-license.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-missing-symbols.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-obsolete-deps.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-you-can-write-your-own.py
    csw/mgar/gar/v2-git/lib/python/package_checks_old.py
    csw/mgar/gar/v2-git/lib/python/package_checks_old_test.py
    csw/mgar/gar/v2-git/lib/python/testdata/stats/
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/all_filenames.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/basic_stats.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/binaries.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/binaries_dump_info.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/depends.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/isalist.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/overrides.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/pkginfo.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/pkgmap.yml

Removed Paths:
-------------
    csw/mgar/gar/v2-git/bin/checkpkg.d/
    csw/mgar/gar/v2-git/lib/checkpkg.d/README
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-actionclasses.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-archall.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-auto.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-basic.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-libs.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-license.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-missing-symbols.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-obsolete-deps.py
    csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-you-can-write-your-own.py
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/all_filenames.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/basic_stats.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/binaries.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/binaries_dump_info.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/depends.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/isalist.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/overrides.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/pkginfo.yml
    csw/mgar/gar/v2-git/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/pkgmap.yml

Property Changed:
----------------
    csw/mgar/gar/v2-git/
    csw/mgar/gar/v2-git/lib/python/checkpkg_test.py
    csw/mgar/gar/v2-git/lib/python/package_checks.py
    csw/mgar/gar/v2-git/lib/python/package_checks_test.py
    csw/mgar/gar/v2-git/pkglib/csw/depend


Property changes on: csw/mgar/gar/v2-git
___________________________________________________________________
Modified: svn:mergeinfo
   - /csw/mgar/gar/v2:4936-6678,6915-8697
/csw/mgar/gar/v2-checkpkg:7722-7855
/csw/mgar/gar/v2-checkpkg-stats:8454-8649
/csw/mgar/gar/v2-collapsed-modulations:6895
/csw/mgar/gar/v2-dirpackage:8125-8180
/csw/mgar/gar/v2-migrateconf:7082-7211
/csw/mgar/gar/v2-skayser:6087-6132
   + /csw/mgar/gar/v2:4936-6678,6915-9127
/csw/mgar/gar/v2-checkpkg:7722-7855
/csw/mgar/gar/v2-checkpkg-stats:8454-8649
/csw/mgar/gar/v2-collapsed-modulations:6895
/csw/mgar/gar/v2-dirpackage:8125-8180
/csw/mgar/gar/v2-migrateconf:7082-7211
/csw/mgar/gar/v2-skayser:6087-6132

Modified: csw/mgar/gar/v2-git/bin/analyze_module_results.py
===================================================================
--- csw/mgar/gar/v2-git/bin/analyze_module_results.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/bin/analyze_module_results.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -34,18 +34,21 @@
         pkgname, tag_name, tag_info = checkpkg.ParseTagLine(line)
         error_tags.append(checkpkg.CheckpkgTag(pkgname, tag_name, tag_info))
   overrides = reduce(lambda x, y: x + y, overrides_list)
-  tags_after_overrides = checkpkg.ApplyOverrides(error_tags, overrides)
+  (tags_after_overrides,
+   unapplied_overrides) = checkpkg.ApplyOverrides(error_tags, overrides)
   exit_code = bool(tags_after_overrides)
   if tags_after_overrides:
     print "There were errors reported."
     print "If you know they are false positives, you can override them:"
     for tag in tags_after_overrides:
-      if tag.tag_info:
-        tag_postfix = "|%s" % tag.tag_info.replace(" ", "|")
-      else:
-        tag_postfix = ""
-      print ("CHECKPKG_OVERRIDES_%s += %s%s"
-             % (tag.pkgname, tag.tag_name, tag_postfix))
+      print tag.ToGarSyntax()
+  if unapplied_overrides:
+    print "WARNING: Some overrides did not match any errors."
+    print "         They can be removed, as they don't take any effect anyway."
+    print "         If you're getting errors at the same time, maybe you didn't"
+    print "         specify the overrides correctly."
+    for override in unapplied_overrides:
+      print "* Unused %s" % override
   sys.exit(exit_code)
 
 

Modified: csw/mgar/gar/v2-git/bin/checkpkg
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/bin/checkpkg	2010-03-13 09:55:32 UTC (rev 9128)
@@ -91,8 +91,10 @@
 	print ERROR: $* >/dev/fd/2
 	cleanup
 	cleanupset
-	print "To run checkpkg in the debug mode, add the '-d' flag:"
+	print "To run checkpkg in the debug mode, add the '-d' flag, for example:"
 	print "${selfpath} -d ${selfargs}"
+	print "After you modify any overrides, you need to do gmake remerge repackage"
+	print "or gmake platforms-remerge platforms-repackage."
 	exit 1
 }
 
@@ -216,109 +218,12 @@
 basedir=`sed -n 's/^BASEDIR=//p' $TMPFILE`
 pkgarch=`sed -n 's/^ARCH=//p' $TMPFILE|head -1`
 
-case `basename $f` in
-	${software}-${version}-*)
-		# file name looks okay
-	;;
-	${software}-*)
-		print ERROR: filename missing full version field $version
-		rm -rf $EXTRACTDIR $TMPARCHIVE
-		 exit 1
-	;;
-	*)
-		print ERROR: filename  should start with $software-$version-
-		rm -rf $EXTRACTDIR $TMPARCHIVE
-		exit  1
-esac
-
-
-
-if [ "$maintname" = "" ] ; then
-	# the old format, in the DESC field
-	maintname=`sed -n 's/^DESC=.*for CSW by //p' $TMPFILE`
-
-	# Since the DESC field has been coopted, take
-	# description from second half of NAME field now.
-	desc=`sed -n 's/^NAME=[^ -]* - //p' $TMPFILE`
-else
-	if [ "$desc" = "" ] ; then
-		desc=`sed -n 's/^NAME=[^ -]* - //p' $TMPFILE`
-	fi
-fi
-
 rm $TMPFILE
 
 # strip out '' chars, because it interferes with mysql
 desc=`print $desc | sed "s/'//g"`
 
 
-print Info for pkg $pkgname
-
-print software= "'$software'"
-print arch= "'$pkgarch'"
-print desc="'$desc'"
-print pkgname="'$pkgname'"
-print version="'$version'"
-print maintainer name="'$maintname'"
-print maint email="'$email'"
-print hotline="'$hotline'"
-if [ "$basedir" != "" ] ; then
-	print basedir="'$basedir'"
-fi
-
-if [[ ${#software} -gt ${NAME_MAX_LENGTH} ]] ; then
-	errmsg "$f: software name longer than ${NAME_MAX_LENGTH} chars"
-fi
-if [[ ${#pkgname} -gt ${NAME_MAX_LENGTH} ]] ; then
-	errmsg "$f: pkg name longer than ${NAME_MAX_LENGTH} chars"
-fi
-
-if [ "$software" = "" ] ; then errmsg $f: software field not set properly in NAME ; fi
-if [ "$pkgname" = "" ] ; then errmsg $f: pkgname field blank ; fi
-if [ "$desc" = "" ] ; then errmsg $f: no description in either NAME or DESC field ; fi
-if [ ${#desc} -gt 100 ] ; then errmsg $f: description greater than 100 chars ; fi
-if [ "$version" = "" ] ; then errmsg $f: VERSION field blank ;  fi
-if [ "$maintname" = "" ] ; then errmsg $f: maintainer name not detected. Fill out VENDOR field properly ; fi
-if [ "$email" = "" ] ; then errmsg $f: EMAIL field blank ; fi
-if [ "$hotline" = "" ] ; then errmsg $f: HOTLINE field blank ; fi
-
-
-case $version in
-	*-*)
-		errmsg "VERSION field not allowed to have \"-\" in it"
-	;;
-	*,REV=20[01][0-9].[0-9][0-9].[0-9][0-9]*)
-		:
-	;;
-	*)
-		print ERROR: no REV=YYYY.MM.DD field in VERSION
-		exit 1
-	;;
-esac
-
-case $pkgarch in
-	sparc|i386|all)
-	;;
-	sparc.*|i386.*)
-	;;
-
-	*)
-	print ERROR: non-standard ARCH def in package: $pkgarch
-	rm -rf $EXTRACTDIR $TMPARCHIVE
-	exit 1
-esac
-
-case $f in
-  *${pkgarch}*)
-    print "f: $f, pkgarch: $pkgarch"
-    ;;
-  *)
-    print "The file name is '$f'."
-    print "The pkgarch is '$pkgarch'."
-    errmsg "ERROR: package file name and pkgarch don't match."
-    ;;
-esac
-
 goodarch=yes
 case $f in
 	*${LOCAL_ARCH}*)
@@ -355,67 +260,6 @@
 
 ########################################
 # Check for some common errors
-if [[ $pkgname != "CSWcommon" ]] ; then
-
-	if [[ $LOGNAME != "root" ]] ; then
-		nawk '$6 == "'$LOGNAME'" {print; exit 1}' $EXTRACTDIR/$pkgname/pkgmap
-		if [[ $? -eq 1 ]] ; then
-			print ERROR: files owned by $LOGNAME in prototype file
-			rm -rf $EXTRACTDIR $TMPARCHIVE
-			exit 1
-		fi
-	fi
-
-	egrep 'd none /opt ' $EXTRACTDIR/$pkgname/pkgmap
-	if [[ $? -eq 0 ]] ; then
-	errmsg You should not have an entry for /opt in your prototype file
-	fi
-	egrep 'd none [^ ]* 06' $EXTRACTDIR/$pkgname/pkgmap
-	if [[ $? -eq 0 ]] ; then
-	errmsg You must have execute permission set on directories
-	fi
-	egrep '/opt/csw/man|d none man' $EXTRACTDIR/$pkgname/pkgmap
-	if [[ $? -eq 0 ]] ; then
-	errmsg /opt/csw/man should not have a directory entry in prototype
-	fi
-	egrep '/opt/csw/doc|d none doc' $EXTRACTDIR/$pkgname/pkgmap
-	if [[ $? -eq 0 ]] ; then
-	errmsg /opt/csw/doc should not have a directory entry in prototype
-	fi
-	egrep '/opt/csw/info|d none info' $EXTRACTDIR/$pkgname/pkgmap
-	if [[ $? -eq 0 ]] ; then
-	errmsg /opt/csw/info should not have a directory entry in prototype
-	fi
-	egrep 'lib/charset.alias' $EXTRACTDIR/$pkgname/pkgmap
-	if [[ $? -eq 0 ]] ; then
-	warnmsg Only CSWiconv should have lib/charset.alias in it
-	fi
-	egrep 'share/locale/locale.alias' $EXTRACTDIR/$pkgname/pkgmap
-	if [[ $? -eq 0 ]] ; then
-	warnmsg Only CSWcommon should have share/locale/locale.alias in it
-	fi
-	fgrep  '? ? ?' $EXTRACTDIR/$pkgname/pkgmap |
-	egrep '[/]opt[/]csw'
-	if [[ $? -eq 0 ]] ; then
-	errmsg "You should only use '? ? ?' for non-csw paths. Use appropriate explicit perms/ownership instead"
-	fi
-	# this is like "installed package info". It is acceptible
-	# to update it in a postinstall script, but not have it
-	# directly in the pkgmap. A "e" entry might be acceptible though.
-	egrep ' f .*/perllocal.pod' $EXTRACTDIR/$pkgname/pkgmap
-	if [[ $? -eq 0 ]] ; then
-	errmsg perllocal.pod should be removed from prototype file
-	fi
-fi
-# special case. sigh.
-if [[ $pkgname != "CSWtexinfo" ]] ; then
-	egrep '/opt/csw/share/info/dir[ ]|none share/info/dir[ ]' $EXTRACTDIR/$pkgname/pkgmap
-	if [[ $? -eq 0 ]] ; then
-	errmsg /opt/csw/share/info/dir should only be in CSWtexinfo
-	rm -rf $EXTRACTDIR $TMPARCHIVE
-	exit 1
-	fi
-fi
 #########################################
 # find all executables and dynamic libs,and list their filenames.
 listbinaries() {
@@ -428,26 +272,15 @@
 	find $1 -print | xargs file |grep ELF |nawk -F: '{print $1}'
 }
 
-
-
-
 if [[ "$goodarch" = "yes" ]] ; then
 	# man ld.so.1 for more info on this hack
 	export LD_NOAUXFLTR=1
-
 	listbinaries $EXTRACTDIR/$pkgname >$EXTRACTDIR/elflist
 	# have to do this for ldd to work. arrg.
 	if [ -s "$EXTRACTDIR/elflist" ] ; then
 		chmod 0755 `cat $EXTRACTDIR/elflist`
-
-	#cat $EXTRACTDIR/elflist| xargs ldd  2>/dev/null |fgrep  '.so' |
-	#              sed 's:^.*=>[^/]*::' | nawk '{print $1}' |sort -u >$EXTRACTDIR/liblist
-
 		cat $EXTRACTDIR/elflist| xargs /usr/ccs/bin/dump -Lv |nawk '$2=="NEEDED"{print $3}' |
 			sort -u | egrep -v $EXTRACTDIR >$EXTRACTDIR/liblist
-
-			
-
 		print libraries used are:
 		cat $EXTRACTDIR/liblist
 		print "cross-referencing with depend file (May take a while)"
@@ -479,14 +312,6 @@
 	errmsg "$pkgname references self in depend file"
 fi
 
-# Verify that there are no multiple depends
-repeated_depends="$(awk '{print $2}' $EXTRACTDIR/$pkgname/install/depend \
-  | sort | uniq -c | awk '{print $1}' | sort | uniq | wc -l)"
-if [[ "$repeated_depends" -gt 1 ]]; then
-        cat $EXTRACTDIR/$pkgname/install/depend
-        errmsg "$pkgname lists a dependency more than once, see above"
-fi
-
 #to retain a record of all packages currently being examined from $@
 echo $pkgname >> $SETDEPS
 
@@ -538,7 +363,7 @@
 set_variables_for_individual_package_check "$f"
 
 test_suite_ok=1
-checkpkg_module_dir=${command_basedir}/checkpkg.d
+checkpkg_module_dir=${command_basedir}/../lib/checkpkg.d
 checkpkg_module_tag="checkpkg-"
 checkpkg_stats_basedir="${HOME}/.checkpkg/stats"
 
@@ -575,7 +400,8 @@
 			plugin_name="`echo ${plugin} | sed -e 's+.*/checkpkg-++' | sed -e 's+\.py$++'`"
 			error_tag_file="tags.${plugin_name}"
 			printf "${BOLD}${module_name_format}${COLOR_RESET} running..." "${plugin_name}"
-			debugmsg "Executing: ${plugin} $extra_options -b \"${checkpkg_stats_basedir}\" -o \"${EXTRACTDIR}/${error_tag_file}\" ${md5sums}"
+			debugmsg "Executing: ${plugin} $extra_options -b \"${checkpkg_stats_basedir}\"" \
+		                 "-o \"${EXTRACTDIR}/${error_tag_file}\" `echo ${md5sums}`"
 			${plugin} \
 				$extra_options \
 				-b "${checkpkg_stats_basedir}" \
@@ -597,7 +423,9 @@
 fi
 
 for log_file in ${log_files}; do
-	if [[ `gwc -c "${log_file}" | awk '{print $1}'` -gt 1 ]]; then
+	log_len=`gsed -e 's/\s\+//g' "${log_file}" | gtr -s '\n' | gwc -c | awk '{print $1}'`
+	if [[ "${log_len}" -gt 1 ]]; then
+		print "printing ${log_file}..."
 		debugmsg ">> LOG START: ${log_file}"
 		cat "${log_file}"
 		debugmsg "<< LOG END: ${log_file}"

Modified: csw/mgar/gar/v2-git/bin/checkpkg_collect_stats.py
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg_collect_stats.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/bin/checkpkg_collect_stats.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -36,7 +36,7 @@
   packages = [opencsw.CswSrv4File(x, options.debug) for x in args]
   stats_list = [checkpkg.PackageStats(pkg) for pkg in packages]
   for pkg_stats in stats_list:
-  	pkg_stats.CollectStats()
+    pkg_stats.CollectStats()
 
 if __name__ == '__main__':
-	main()
+  main()

Modified: csw/mgar/gar/v2-git/bin/update_contents_cache.py
===================================================================
--- csw/mgar/gar/v2-git/bin/update_contents_cache.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/bin/update_contents_cache.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -21,6 +21,7 @@
   print "Checking if the package cache is up to date."
   logging.basicConfig(level=logging.INFO)
   test_pkgmap = checkpkg.SystemPkgmap()
+  test_pkgmap.InitializeDatabase()
 
 
 if __name__ == '__main__':

Modified: csw/mgar/gar/v2-git/categories/gnome/category.mk
===================================================================
--- csw/mgar/gar/v2-git/categories/gnome/category.mk	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/categories/gnome/category.mk	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,5 +1,5 @@
 # pkg-config options
-EXTRA_PKG_CONFIG_PATH += /opt/csw/X11/lib/pkgconfig
+EXTRA_PKG_CONFIG_DIRS += /opt/csw/X11/lib
 
 MSGFMT= /opt/csw/bin/gmsgfmt
 MSGMERGE= /opt/csw/bin/gmsgmerge
@@ -10,4 +10,10 @@
 export XGETTEXT
 export GETTEXT
 
+# Perhaps there is a category-level variable set?
+EXTRA_INC += /opt/csw/X11/include
+EXTRA_INC += /usr/X11/include
+EXTRA_INC += /usr/openwin/share/include
+EXTRA_LIB += /opt/csw/X11/lib
+
 include gar/gar.mk

Modified: csw/mgar/gar/v2-git/categories/python/category.mk
===================================================================
--- csw/mgar/gar/v2-git/categories/python/category.mk	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/categories/python/category.mk	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,8 +1,11 @@
 # Add a dependency to CSWpython
 _EXTRA_GAR_PKGS += CSWpython
 
-# Exclude egg-info files (only needed for easy_install)
-_MERGE_EXCLUDE_CATEGORY += .*\.egg-info.*
+# For the record, do not include the following line:
+# _MERGE_EXCLUDE_CATEGORY += .*\.egg-info.*
+#
+# It breaks pysetuptools and trac.  Here's a relevant reading:
+# http://fedoraproject.org/wiki/Packaging:Python#Packaging_eggs_and_setuptools_concerns
 
 # Activate cswpycompile support to exclude .pyc and .pyo files from 
 # the package and compile them on installation. File exclusion is 

Modified: csw/mgar/gar/v2-git/gar.conf.mk
===================================================================
--- csw/mgar/gar/v2-git/gar.conf.mk	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/gar.conf.mk	2010-03-13 09:55:32 UTC (rev 9128)
@@ -14,7 +14,7 @@
 -include /etc/opt/csw/garrc
 -include /opt/csw/etc/garrc
 
-THISHOST := $(shell uname -n)
+THISHOST := $(shell /usr/bin/uname -n)
 
 # On these platforms packages are built.
 # They will include binaries for all ISAs that are specified for the platform.
@@ -24,11 +24,11 @@
 # invoked from "gmake platforms" or when you build a package on a host
 # that is suitable for the platform.
 # If there are no platform hosts defined the feature is disabled.
-PLATFORM ?= $(firstword $(foreach P,$(PACKAGING_PLATFORMS),$(if $(filter $(THISHOST),$(PACKAGING_HOST_$P)),$P)))
+GAR_PLATFORM ?= $(firstword $(foreach P,$(PACKAGING_PLATFORMS),$(if $(filter $(THISHOST),$(PACKAGING_HOST_$P)),$P)))
 
 MODULATION ?= global
 FILEDIR ?= files
-WORKROOTDIR ?= $(if $(PLATFORM),work/$(PLATFORM),work)
+WORKROOTDIR ?= $(if $(GAR_PLATFORM),work/$(GAR_PLATFORM),work)
 WORKDIR ?= $(WORKROOTDIR)/build-$(MODULATION)
 WORKDIR_FIRSTMOD ?= $(WORKROOTDIR)/build-$(firstword $(MODULATIONS))
 DOWNLOADDIR ?= $(WORKROOTDIR)/download
@@ -102,8 +102,8 @@
 
 # Architecture
 GARCHLIST ?= sparc i386
-GARCH    ?= $(shell uname -p)
-GAROSREL ?= $(shell uname -r)
+GARCH    := $(if $(GARCH),$(GARCH),$(shell /usr/bin/uname -p))
+GAROSREL := $(if $(GAROSREL),$(GAROSREL),$(shell /usr/bin/uname -r))
 
 
 # These are the standard directory name variables from all GNU

Modified: csw/mgar/gar/v2-git/gar.lib.mk
===================================================================
--- csw/mgar/gar/v2-git/gar.lib.mk	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/gar.lib.mk	2010-03-13 09:55:32 UTC (rev 9128)
@@ -568,12 +568,12 @@
 # Run tests on pre-built sources
 test-%/Makefile:
 	@echo " ==> Running make $(TEST_TARGET) in $*"
-	@$(TEST_ENV) $(MAKE) $(foreach TTT,$(foreach TTT,$(TEST_OVERRIDE_VARS),$(TTT)="$(TEST_OVERRIDE_VAR_$(TTT))") $(TEST_OVERRIDE_DIRS),$(TTT)="$($(TTT))") -C $* $(TEST_ARGS) $(TEST_TARGET)
+	@$(TEST_ENV) $(MAKE) $(foreach TTT,$(TEST_OVERRIDE_VARS),$(TTT)="$(TEST_OVERRIDE_VAR_$(TTT))") $(foreach TTT,$(TEST_OVERRIDE_DIRS),$(TTT)="$($(TTT))") -C $* $(TEST_ARGS) $(TEST_TARGET)
 	@$(MAKECOOKIE)
 
 test-%/makefile:
 	@echo " ==> Running make $(TEST_TARGET) in $*"
-	@$(TEST_ENV) $(MAKE) $(foreach TTT,$(foreach TTT,$(TEST_OVERRIDE_VARS),$(TTT)="$(TEST_OVERRIDE_VAR_$(TTT))") $(TEST_OVERRIDE_DIRS),$(TTT)="$($(TTT))") -C $* $(TEST_ARGS) $(TEST_TARGET)
+	@$(TEST_ENV) $(MAKE) $(foreach TTT,$(TEST_OVERRIDE_VARS),$(TTT)="$(TEST_OVERRIDE_VAR_$(TTT))") $(foreach TTT,$(TEST_OVERRIDE_DIRS),$(TTT)="$($(TTT))") -C $* $(TEST_ARGS) $(TEST_TARGET)
 	@$(MAKECOOKIE)
 
 test-%/GNUmakefile:

Modified: csw/mgar/gar/v2-git/gar.mk
===================================================================
--- csw/mgar/gar/v2-git/gar.mk	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/gar.mk	2010-03-13 09:55:32 UTC (rev 9128)
@@ -135,8 +135,8 @@
 merge-$(2):
 	@echo "[===== Building modulation '$(2)' on host '$$(BUILDHOST)' =====]"
 	$$(if $$(and $$(BUILDHOST),$$(filter-out $$(THISHOST),$$(BUILDHOST))),\
-		$(SSH) $$(BUILDHOST) "PATH=$$(PATH) $(MAKE) -C $$(CURDIR) $(if $(PLATFORM),PLATFORM=$(PLATFORM)) MODULATION=$(2) $(3) merge-modulated",\
-		$(MAKE) $(if $(PLATFORM),PLATFORM=$(PLATFORM)) MODULATION=$(2) $(3) merge-modulated\
+		$(SSH) $$(BUILDHOST) "PATH=$$(PATH) $(MAKE) -C $$(CURDIR) $(if $(GAR_PLATFORM),GAR_PLATFORM=$(GAR_PLATFORM)) MODULATION=$(2) $(3) merge-modulated",\
+		$(MAKE) $(if $(GAR_PLATFORM),GAR_PLATFORM=$(GAR_PLATFORM)) MODULATION=$(2) $(3) merge-modulated\
 	)
 	@# The next line has intentionally been left blank to explicitly terminate this make rule
 
@@ -361,10 +361,12 @@
 MAKESUM_TARGETS =  $(filter-out $(_NOCHECKSUM) $(NOCHECKSUM),$(ALLFILES))
 
 makesum: fetch $(addprefix $(DOWNLOADDIR)/,$(MAKESUM_TARGETS)) $(GARCHIVE_TARGETS)
-	@if test "x$(MAKESUM_TARGETS)" != "x "; then \
+	@if test "x$(MAKESUM_TARGETS)" != "x"; then \
 		(cd $(DOWNLOADDIR) && gmd5sum $(MAKESUM_TARGETS)) > $(CHECKSUM_FILE) ; \
 		echo "Checksums made for $(MAKESUM_TARGETS)" ; \
 		cat $(CHECKSUM_FILE) ; \
+	else \
+		cp /dev/null $(CHECKSUM_FILE) ; \
 	fi
 
 # I am always typing this by mistake

Modified: csw/mgar/gar/v2-git/gar.pkg.mk
===================================================================
--- csw/mgar/gar/v2-git/gar.pkg.mk	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/gar.pkg.mk	2010-03-13 09:55:32 UTC (rev 9128)
@@ -32,7 +32,7 @@
 
 ifeq ($(origin PACKAGES), undefined)
 PACKAGES        = $(if $(filter %.gspec,$(DISTFILES)),,CSW$(GARNAME))
-CATALOGNAME     = $(if $(filter %.gspec,$(DISTFILES)),,$(GARNAME))
+CATALOGNAME    ?= $(if $(filter %.gspec,$(DISTFILES)),,$(GARNAME))
 SRCPACKAGE_BASE = $(firstword $(basename $(filter %.gspec,$(DISTFILES))) $(PACKAGES))
 SRCPACKAGE     ?= $(SRCPACKAGE_BASE)-src
 SPKG_SPECS     ?= $(basename $(filter %.gspec,$(DISTFILES))) $(PACKAGES) $(if $(NOSOURCEPACKAGE),,$(SRCPACKAGE))
@@ -155,7 +155,7 @@
 SPKG_PSTAMP    ?= $(LOGNAME)@$(shell hostname)-$(call _REVISION)-$(shell date '+%Y%m%d%H%M%S')
 SPKG_BASEDIR   ?= $(prefix)
 SPKG_CLASSES   ?= none
-SPKG_OSNAME    ?= $(shell uname -s)$(shell uname -r)
+SPKG_OSNAME    := $(if $(SPKG_OSNAME),$(SPKG_OSNAME),$(shell /usr/bin/uname -s)$(shell /usr/bin/uname -r))
 
 SPKG_SPOOLROOT ?= $(DESTROOT)
 SPKG_SPOOLDIR  ?= $(SPKG_SPOOLROOT)/spool.$(GAROSREL)-$(GARCH)
@@ -354,7 +354,7 @@
 
 _PROTOTYPE_MODIFIERS = | perl -ane '\
 		$(foreach M,$(PROTOTYPE_MODIFIERS),\
-			$(if $(PROTOTYPE_FILES_$M),if( $$F[2] =~ m(^$(shell echo $(PROTOTYPE_FILES_$M) | /usr/bin/tr " " "|")$$) ) {)\
+			$(if $(PROTOTYPE_FILES_$M),if( $$F[2] =~ m(^$(firstword $(PROTOTYPE_FILES_$M))$(foreach F,$(wordlist 2,$(words $(PROTOTYPE_FILES_$M)),$(PROTOTYPE_FILES_$M)),|$F)$$) ) {)\
 				$(if $(PROTOTYPE_FTYPE_$M),$$F[0] = "$(PROTOTYPE_FTYPE_$M)";)\
 				$(if $(PROTOTYPE_CLASS_$M),$$F[1] = "$(PROTOTYPE_CLASS_$M)";)\
 				$(if $(PROTOTYPE_PERMS_$M),$$F[3] = "$(PROTOTYPE_PERMS_$M)";)\
@@ -447,6 +447,7 @@
 $(WORKDIR)/%.depend: _EXTRA_GAR_PKGS += $(if $(strip $(shell cat $(WORKDIR)/$*.prototype | perl -ane 'print "yes" if( $$F[1] eq "cswalternatives")')),CSWalternatives)
 $(WORKDIR)/%.depend: _EXTRA_GAR_PKGS += $(if $(strip $(shell cat $(WORKDIR)/$*.prototype | perl -ane '$(foreach C,$(_CSWCLASSES),print "$C\n" if( $$F[1] eq "$C");)')),CSWcswclassutils)
 
+# The final "true" is for packages without dependencies to make the shell happy as "( )" is not allowed.
 $(WORKDIR)/%.depend: $(WORKDIR)
 	$(_DBG)$(if $(_EXTRA_GAR_PKGS)$(RUNTIME_DEP_PKGS_$*)$(RUNTIME_DEP_PKGS)$(DEP_PKGS)$(DEP_PKGS_$*)$(INCOMPATIBLE_PKGS)$(INCOMPATIBLE_PKGS_$*), \
 		($(foreach PKG,$(INCOMPATIBLE_PKGS_$*) $(INCOMPATIBLE_PKGS),\
@@ -457,7 +458,8 @@
 				echo "P $(PKG) $(call catalogname,$(PKG)) - $(SPKG_DESC_$(PKG))";, \
 				echo "$(shell (/usr/bin/pkginfo $(PKG) || echo "P $(PKG) - ") | $(GAWK) '{ $$1 = "P"; print } ')"; \
 			) \
-		)) >$@)
+		) \
+		true) >$@)
 
 # Dynamic gspec-files are constructed as follows:
 # - Packages using dynamic gspec-files must be listed in PACKAGES
@@ -690,8 +692,11 @@
 merge-alternatives-%:
 	@echo "[ Generating alternatives for package $* ]"
 	$(_DBG)ginstall -d $(PKGROOT)/opt/csw/share/alternatives
-	$(_DBG)($(foreach A,$(or $(ALTERNATIVES_$*),$(ALTERNATIVES)),echo "$(ALTERNATIVE_$A)";)) \
-		> $(PKGROOT)/opt/csw/share/alternatives/$(call catalogname,$*)
+	$(_DBG)($(foreach A,$(or $(ALTERNATIVES_$*),$(ALTERNATIVES)), \
+		$(if $(ALTERNATIVE_$A), \
+			echo "$(ALTERNATIVE_$A)";, \
+			$(error The variable 'ALTERNATIVE_$A' is empty, but must contain an alternative) \
+		))) > $(PKGROOT)/opt/csw/share/alternatives/$(call catalogname,$*)
 	@$(MAKECOOKIE)
 
 merge-alternatives: $(foreach S,$(SPKG_SPECS),$(if $(or $(ALTERNATIVES_$S),$(ALTERNATIVES)),merge-alternatives-$S))
@@ -757,7 +762,7 @@
 				if test -f "$$F" -a \! -h "$$F"; then echo $$F; fi;     \
 			done)),)
 _buildpackage: _EXTRA_GAR_PKGS += $(if $(ISAEXEC_FILES),CSWisaexec)
-_buildpackage: pre-package $(PACKAGE_TARGETS) post-package $(if $(ENABLE_CHECK),pkgcheck)
+_buildpackage: pre-package $(PACKAGE_TARGETS) post-package $(if $(filter-out 0,$(ENABLE_CHECK)),pkgcheck)
 
 _package: validateplatform extract-global merge $(SPKG_DESTDIRS) _buildpackage
 	@$(MAKECOOKIE)
@@ -766,7 +771,7 @@
 	@echo
 	@echo "The following packages have been built:"
 	@echo
-	@$(MAKE) -s PLATFORM=$(PLATFORM) _pkgshow
+	@$(MAKE) -s GAR_PLATFORM=$(GAR_PLATFORM) _pkgshow
 	@echo
 	@$(DONADA)
 
@@ -775,7 +780,7 @@
 dirpackage: _package
 	@echo "The following packages have been built:"
 	@echo
-	@$(MAKE) -s PLATFORM=$(PLATFORM) _dirpkgshow
+	@$(MAKE) -s GAR_PLATFORM=$(GAR_PLATFORM) _dirpkgshow
 	@echo
 	@$(DONADA)
 
@@ -840,8 +845,8 @@
 	$(foreach P,$(_PACKAGING_PLATFORMS),\
 		$(if $(PACKAGING_HOST_$P),\
 			$(if $(filter $(THISHOST),$(PACKAGING_HOST_$P)),\
-				$(MAKE) PLATFORM=$P _package && ,\
-				$(SSH) -t $(PACKAGING_HOST_$P) "PATH=$$PATH:/opt/csw/bin $(MAKE) -C $(CURDIR) PLATFORM=$P _package" && \
+				$(MAKE) GAR_PLATFORM=$P _package && ,\
+				$(SSH) -t $(PACKAGING_HOST_$P) "PATH=$$PATH:/opt/csw/bin $(MAKE) -C $(CURDIR) GAR_PLATFORM=$P _package" && \
 			),\
 			$(error *** No host has been defined for platform $P)\
 		)\
@@ -854,9 +859,9 @@
 		$(if $(ARCHALL),echo " (suitable for all architectures)\c";) \
 		$(if $(filter $(THISHOST),$(PACKAGING_HOST_$P)),\
 			echo " (built on this host)";\
-			  $(MAKE) -s PLATFORM=$P _pkgshow;echo;,\
+			  $(MAKE) -s GAR_PLATFORM=$P _pkgshow;echo;,\
 			echo " (built on host '$(PACKAGING_HOST_$P)')";\
-			  $(SSH) $(PACKAGING_HOST_$P) "PATH=$$PATH:/opt/csw/bin $(MAKE) -C $(CURDIR) -s PLATFORM=$P _pkgshow";echo;\
+			  $(SSH) $(PACKAGING_HOST_$P) "PATH=$$PATH:/opt/csw/bin $(MAKE) -C $(CURDIR) -s GAR_PLATFORM=$P _pkgshow";echo;\
 		)\
 	)
 	@$(MAKECOOKIE)
@@ -866,8 +871,8 @@
 	$(foreach P,$(_PACKAGING_PLATFORMS),\
 		$(if $(PACKAGING_HOST_$P),\
 			$(if $(filter $(THISHOST),$(PACKAGING_HOST_$P)),\
-				$(MAKE) -s PLATFORM=$P $* && ,\
-				$(SSH) -t $(PACKAGING_HOST_$P) "PATH=$$PATH:/opt/csw/bin $(MAKE) -C $(CURDIR) PLATFORM=$P $*" && \
+				$(MAKE) -s GAR_PLATFORM=$P $* && ,\
+				$(SSH) -t $(PACKAGING_HOST_$P) "PATH=$$PATH:/opt/csw/bin $(MAKE) -C $(CURDIR) GAR_PLATFORM=$P $*" && \
 			),\
 			$(error *** No host has been defined for platform $P)\
 		)\

Deleted: csw/mgar/gar/v2-git/lib/checkpkg.d/README
===================================================================
--- csw/mgar/gar/v2/lib/checkpkg.d/README	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/README	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,13 +0,0 @@
-$Id$
-
-This directory contains modular checks.  Each check is an executable file,
-written in any language, accepting specific command line options and returning
-the result by writing to a text file.
-
-To see the required flags, issue:
-
-./checkpkg-you-can-write-your-own.py -h
-
-Each test's file name must begin with "checkpkg-".
-
-See http://wiki.opencsw.org/checkpkg for more information.

Copied: csw/mgar/gar/v2-git/lib/checkpkg.d/README (from rev 9127, csw/mgar/gar/v2/lib/checkpkg.d/README)
===================================================================
--- csw/mgar/gar/v2-git/lib/checkpkg.d/README	                        (rev 0)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/README	2010-03-13 09:55:32 UTC (rev 9128)
@@ -0,0 +1,13 @@
+$Id$
+
+This directory contains modular checks.  Each check is an executable file,
+written in any language, accepting specific command line options and returning
+the result by writing to a text file.
+
+To see the required flags, issue:
+
+./checkpkg-you-can-write-your-own.py -h
+
+Each test's file name must begin with "checkpkg-".
+
+See http://wiki.opencsw.org/checkpkg for more information.

Deleted: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-actionclasses.py
===================================================================
--- csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-actionclasses.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-actionclasses.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,75 +0,0 @@
-#!/opt/csw/bin/python2.6
-# $Id$
-
-"""This is a dummy check. You can use it as a boilerplate for your own checks.
-
-Copy it and modify.
-"""
-
-import logging
-import os.path
-import sys
-import re
-
-CHECKPKG_MODULE_NAME = "class action scripts / prototype integrity"
-
-# The following bit of code sets the correct path to Python libraries
-# distributed with GAR.
-path_list = [os.path.dirname(__file__),
-             "..", "..", "lib", "python"]
-sys.path.append(os.path.join(*path_list))
-import checkpkg
-import opencsw
-
-
-def CheckActionClasses(pkg_data, debug):
-  """Checks the consistency between classes in the prototype and pkginfo."""
-  errors = []
-  pkginfo = pkg_data["pkginfo"]
-  pkgmap = pkg_data["pkgmap"]
-  pkginfo_classes = set(re.split(opencsw.WS_RE, pkginfo["CLASSES"]))
-  pkgmap_classes = set()
-  for entry in pkgmap:
-    if entry["class"]:  # might be None
-      pkgmap_classes.add(entry["class"])
-  only_in_pkginfo = pkginfo_classes.difference(pkgmap_classes)
-  only_in_pkgmap = pkgmap_classes.difference(pkginfo_classes)
-  for action_class in only_in_pkginfo:
-    error = checkpkg.CheckpkgTag(
-        pkg_data["basic_stats"]["pkgname"],
-        "action-class-only-in-pkginfo",
-        action_class,
-        msg="This shouldn't cause any problems, but it might be not necessary.")
-    errors.append(error)
-  for action_class in only_in_pkgmap:
-    errors.append(
-        checkpkg.CheckpkgTag(pkg.pkgname, "action-class-only-in-pkgmap", action_class))
-  return errors
-
-
-def main():
-  options, args = checkpkg.GetOptions()
-  if options.debug:
-  	logging.basicConfig(level=logging.DEBUG)
-  else:
-  	logging.basicConfig(level=logging.INFO)
-  md5sums = args
-  # CheckpkgManager class abstracts away things such as the collection of
-  # results.
-  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
-                                           options.stats_basedir,
-                                           md5sums,
-                                           options.debug)
-  # Registering functions defined above.
-  check_manager.RegisterIndividualCheck(CheckActionClasses)
-  # Running the checks, reporting and exiting.
-  exit_code, screen_report, tags_report = check_manager.Run()
-  f = open(options.output, "w")
-  f.write(tags_report)
-  f.close()
-  print screen_report.strip()
-  sys.exit(exit_code)
-
-
-if __name__ == '__main__':
-  main()

Copied: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-actionclasses.py (from rev 9127, csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-actionclasses.py)
===================================================================
--- csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-actionclasses.py	                        (rev 0)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-actionclasses.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -0,0 +1,75 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+"""This is a dummy check. You can use it as a boilerplate for your own checks.
+
+Copy it and modify.
+"""
+
+import logging
+import os.path
+import sys
+import re
+
+CHECKPKG_MODULE_NAME = "class action scripts / prototype integrity"
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+             "..", "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+import opencsw
+
+
+def CheckActionClasses(pkg_data, debug):
+  """Checks the consistency between classes in the prototype and pkginfo."""
+  errors = []
+  pkginfo = pkg_data["pkginfo"]
+  pkgmap = pkg_data["pkgmap"]
+  pkginfo_classes = set(re.split(opencsw.WS_RE, pkginfo["CLASSES"]))
+  pkgmap_classes = set()
+  for entry in pkgmap:
+    if entry["class"]:  # might be None
+      pkgmap_classes.add(entry["class"])
+  only_in_pkginfo = pkginfo_classes.difference(pkgmap_classes)
+  only_in_pkgmap = pkgmap_classes.difference(pkginfo_classes)
+  for action_class in only_in_pkginfo:
+    error = checkpkg.CheckpkgTag(
+        pkg_data["basic_stats"]["pkgname"],
+        "action-class-only-in-pkginfo",
+        action_class,
+        msg="This shouldn't cause any problems, but it might be not necessary.")
+    errors.append(error)
+  for action_class in only_in_pkgmap:
+    errors.append(
+        checkpkg.CheckpkgTag(pkg.pkgname, "action-class-only-in-pkgmap", action_class))
+  return errors
+
+
+def main():
+  options, args = checkpkg.GetOptions()
+  if options.debug:
+  	logging.basicConfig(level=logging.DEBUG)
+  else:
+  	logging.basicConfig(level=logging.INFO)
+  md5sums = args
+  # CheckpkgManager class abstracts away things such as the collection of
+  # results.
+  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
+                                           options.stats_basedir,
+                                           md5sums,
+                                           options.debug)
+  # Registering functions defined above.
+  check_manager.RegisterIndividualCheck(CheckActionClasses)
+  # Running the checks, reporting and exiting.
+  exit_code, screen_report, tags_report = check_manager.Run()
+  f = open(options.output, "w")
+  f.write(tags_report)
+  f.close()
+  print screen_report.strip()
+  sys.exit(exit_code)
+
+
+if __name__ == '__main__':
+  main()

Deleted: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-archall.py
===================================================================
--- csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-archall.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-archall.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,44 +0,0 @@
-#!/opt/csw/bin/python2.6
-#
-# $Id$
-
-"""Verifies the architecture of the package."""
-
-import os.path
-import re
-import sys
-
-CHECKPKG_MODULE_NAME = "architecture check"
-
-# The following bit of code sets the correct path to Python libraries
-# distributed with GAR.
-path_list = [os.path.dirname(__file__),
-             "..", "..", "lib", "python"]
-sys.path.append(os.path.join(*path_list))
-import checkpkg
-import package_checks_old
-
-def main():
-  options, args = checkpkg.GetOptions()
-  md5sums = args
-  # CheckpkgManager class abstracts away things such as the collection of
-  # results.
-  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
-                                           options.stats_basedir,
-                                           md5sums,
-                                           options.debug)
-
-  check_manager.RegisterIndividualCheck(
-      package_checks_old.CheckArchitectureVsContents)
-  exit_code, screen_report, tags_report = check_manager.Run()
-  f = open(options.output, "w")
-  f.write(tags_report)
-  f.close()
-  print screen_report.strip()
-  sys.exit(exit_code)
-
-
-if __name__ == '__main__':
-  main()
-
-# vim:set sw=2 ts=2 sts=2 expandtab:

Copied: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-archall.py (from rev 9127, csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-archall.py)
===================================================================
--- csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-archall.py	                        (rev 0)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-archall.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -0,0 +1,44 @@
+#!/opt/csw/bin/python2.6
+#
+# $Id$
+
+"""Verifies the architecture of the package."""
+
+import os.path
+import re
+import sys
+
+CHECKPKG_MODULE_NAME = "architecture check"
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+             "..", "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+import package_checks_old
+
+def main():
+  options, args = checkpkg.GetOptions()
+  md5sums = args
+  # CheckpkgManager class abstracts away things such as the collection of
+  # results.
+  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
+                                           options.stats_basedir,
+                                           md5sums,
+                                           options.debug)
+
+  check_manager.RegisterIndividualCheck(
+      package_checks_old.CheckArchitectureVsContents)
+  exit_code, screen_report, tags_report = check_manager.Run()
+  f = open(options.output, "w")
+  f.write(tags_report)
+  f.close()
+  print screen_report.strip()
+  sys.exit(exit_code)
+
+
+if __name__ == '__main__':
+  main()
+
+# vim:set sw=2 ts=2 sts=2 expandtab:

Deleted: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-auto.py
===================================================================
--- csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-auto.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-auto.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,48 +0,0 @@
-#!/opt/csw/bin/python2.6
-# $Id$
-
-"""This is a dummy check. You can use it as a boilerplate for your own checks.
-
-Copy it and modify.
-"""
-
-import logging
-import os.path
-import sys
-import re
-
-CHECKPKG_MODULE_NAME = "Second checkpkg API version"
-
-# The following bit of code sets the correct path to Python libraries
-# distributed with GAR.
-path_list = [os.path.dirname(__file__),
-             "..", "..", "lib", "python"]
-sys.path.append(os.path.join(*path_list))
-import checkpkg
-import opencsw
-
-
-def main():
-  options, args = checkpkg.GetOptions()
-  if options.debug:
-    logging.basicConfig(level=logging.DEBUG)
-  else:
-    logging.basicConfig(level=logging.INFO)
-  md5sums = args
-  # CheckpkgManager2 class abstracts away things such as the collection of
-  # results.
-  check_manager = checkpkg.CheckpkgManager2(CHECKPKG_MODULE_NAME,
-                                            options.stats_basedir,
-                                            md5sums,
-                                            options.debug)
-  # Running the checks, reporting and exiting.
-  exit_code, screen_report, tags_report = check_manager.Run()
-  f = open(options.output, "w")
-  f.write(tags_report)
-  f.close()
-  print screen_report.strip()
-  sys.exit(exit_code)
-
-
-if __name__ == '__main__':
-  main()

Copied: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-auto.py (from rev 9127, csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-auto.py)
===================================================================
--- csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-auto.py	                        (rev 0)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-auto.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -0,0 +1,48 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+"""This is a dummy check. You can use it as a boilerplate for your own checks.
+
+Copy it and modify.
+"""
+
+import logging
+import os.path
+import sys
+import re
+
+CHECKPKG_MODULE_NAME = "Second checkpkg API version"
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+             "..", "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+import opencsw
+
+
+def main():
+  options, args = checkpkg.GetOptions()
+  if options.debug:
+    logging.basicConfig(level=logging.DEBUG)
+  else:
+    logging.basicConfig(level=logging.INFO)
+  md5sums = args
+  # CheckpkgManager2 class abstracts away things such as the collection of
+  # results.
+  check_manager = checkpkg.CheckpkgManager2(CHECKPKG_MODULE_NAME,
+                                            options.stats_basedir,
+                                            md5sums,
+                                            options.debug)
+  # Running the checks, reporting and exiting.
+  exit_code, screen_report, tags_report = check_manager.Run()
+  f = open(options.output, "w")
+  f.write(tags_report)
+  f.close()
+  print screen_report.strip()
+  sys.exit(exit_code)
+
+
+if __name__ == '__main__':
+  main()

Deleted: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-basic.py
===================================================================
--- csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-basic.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-basic.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,48 +0,0 @@
-#!/opt/csw/bin/python2.6
-# $Id$
-
-"""This is a dummy module. You can use it as a boilerplate for your own modules.
-
-Copy it and modify.
-"""
-
-import os.path
-import sys
-
-CHECKPKG_MODULE_NAME = "basic checks ported from Korn shell"
-
-# The following bit of code sets the correct path to Python libraries
-# distributed with GAR.
-path_list = [os.path.dirname(__file__),
-             "..", "..", "lib", "python"]
-sys.path.append(os.path.join(*path_list))
-import checkpkg
-import package_checks_old
-
-def main():
-  options, args = checkpkg.GetOptions()
-  md5sums = args
-  # CheckpkgManager class abstracts away things such as the collection of
-  # results.
-  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
-                                           options.stats_basedir,
-                                           md5sums,
-                                           options.debug)
-  # Registering functions defined above.
-  check_manager.RegisterIndividualCheck(package_checks_old.CatalognameLowercase)
-  check_manager.RegisterIndividualCheck(package_checks_old.FileNameSanity)
-  check_manager.RegisterIndividualCheck(package_checks_old.PkginfoSanity)
-  check_manager.RegisterIndividualCheck(package_checks_old.ArchitectureSanity)
-  check_manager.RegisterIndividualCheck(package_checks_old.CheckBuildingUser)
-  check_manager.RegisterIndividualCheck(package_checks_old.CheckPkgmapPaths)
-  # Running the checks, reporting and exiting.
-  exit_code, screen_report, tags_report = check_manager.Run()
-  f = open(options.output, "w")
-  f.write(tags_report)
-  f.close()
-  print screen_report.strip()
-  sys.exit(exit_code)
-
-
-if __name__ == '__main__':
-  main()

Copied: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-basic.py (from rev 9127, csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-basic.py)
===================================================================
--- csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-basic.py	                        (rev 0)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-basic.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -0,0 +1,48 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+"""This is a dummy module. You can use it as a boilerplate for your own modules.
+
+Copy it and modify.
+"""
+
+import os.path
+import sys
+
+CHECKPKG_MODULE_NAME = "basic checks ported from Korn shell"
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+             "..", "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+import package_checks_old
+
+def main():
+  options, args = checkpkg.GetOptions()
+  md5sums = args
+  # CheckpkgManager class abstracts away things such as the collection of
+  # results.
+  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
+                                           options.stats_basedir,
+                                           md5sums,
+                                           options.debug)
+  # Registering functions defined above.
+  check_manager.RegisterIndividualCheck(package_checks_old.CatalognameLowercase)
+  check_manager.RegisterIndividualCheck(package_checks_old.FileNameSanity)
+  check_manager.RegisterIndividualCheck(package_checks_old.PkginfoSanity)
+  check_manager.RegisterIndividualCheck(package_checks_old.ArchitectureSanity)
+  check_manager.RegisterIndividualCheck(package_checks_old.CheckBuildingUser)
+  check_manager.RegisterIndividualCheck(package_checks_old.CheckPkgmapPaths)
+  # Running the checks, reporting and exiting.
+  exit_code, screen_report, tags_report = check_manager.Run()
+  f = open(options.output, "w")
+  f.write(tags_report)
+  f.close()
+  print screen_report.strip()
+  sys.exit(exit_code)
+
+
+if __name__ == '__main__':
+  main()

Deleted: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-libs.py
===================================================================
--- csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-libs.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-libs.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,185 +0,0 @@
-#!/opt/csw/bin/python2.6
-#
-# $Id$
-
-"""A check for dependencies between shared libraries.
-This is currently more of a prototype than a mature program, but it has some
-unit tests and it appears to be working.  The main problem is that it's not
-divided into smaller testable sections.
-"""
-
-import os
-import os.path
-import copy
-import re
-import subprocess
-import logging
-import sys
-import textwrap
-from Cheetah import Template
-
-CHECKPKG_MODULE_NAME = "shared library linking consistency"
-
-# The following bit of code sets the correct path to Python libraries
-# distributed with GAR.
-path_list = [os.path.dirname(__file__),
-             "..", "..", "lib", "python"]
-sys.path.append(os.path.join(*path_list))
-import checkpkg
-import opencsw
-
-def CheckSharedLibraryConsistency(pkgs_data, debug):
-  ws_re = re.compile(r"\s+")
-  result_ok = True
-  errors = []
-  binaries = []
-  binaries_by_pkgname = {}
-  sonames_by_pkgname = {}
-  pkg_by_any_filename = {}
-  needed_sonames_by_binary = {}
-  filenames_by_soname = {}
-  for pkg_data in pkgs_data:
-    binaries_base = [os.path.basename(x) for x in pkg_data["binaries"]]
-    pkgname = pkg_data["basic_stats"]["pkgname"]
-    binaries_by_pkgname[pkgname] = binaries_base
-    binaries.extend(pkg_data["binaries"])
-    for filename in pkg_data["all_filenames"]:
-      pkg_by_any_filename[filename] = pkgname
-    for binary_data in pkg_data["binaries_dump_info"]:
-      binary_base_name = os.path.basename(binary_data["base_name"])
-      needed_sonames_by_binary[binary_base_name] = binary_data
-      filenames_by_soname[binary_data[checkpkg.SONAME]] = binary_base_name
-    
-  # Making the binaries unique
-  binaries = set(binaries)
-  isalist = pkg_data["isalist"]
-
-  # Building indexes by soname to simplify further processing
-  # These are indexes "by soname".
-  (needed_sonames,
-   binaries_by_soname,
-   runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
-       needed_sonames_by_binary)
-
-  pkgmap = checkpkg.SystemPkgmap()
-  logging.debug("Determining the soname-package relationships.")
-  # lines by soname is an equivalent of $EXTRACTDIR/shortcatalog
-  runpath_data_by_soname = {}
-  for soname in needed_sonames:
-    runpath_data_by_soname[soname] = pkgmap.GetPkgmapLineByBasename(soname)
-  lines_by_soname = checkpkg.GetLinesBySoname(
-      runpath_data_by_soname, needed_sonames, runpath_by_needed_soname, isalist)
-
-  # Creating a map from files to packages.
-  pkgs_by_filename = {}
-  for soname, line in lines_by_soname.iteritems():
-    # TODO: Find all the packages, not just the last field.
-    fields = re.split(ws_re, line.strip())
-    # For now, we'll assume that the last field is the package.
-    pkgname = fields[-1]
-    pkgs_by_filename[soname] = pkgname
-
-  # A shared object dependency/provisioning report, plus checking.
-  #
-  # This section is somewhat overlapping with checkpkg.AnalyzeDependencies(),
-  # it has a different purpose: it reports the relationships between shared
-  # libraries, binaries using them and packages providing them.  Ideally, the
-  # same bit of code would do both checking and reporting.
-  #
-  # TODO: Rewrite this using cheetah templates
-  if debug and needed_sonames:
-    print "Analysis of sonames needed by the package set:"
-    binaries_with_missing_sonames = set([])
-    for soname in needed_sonames:
-      logging.debug("Analyzing: %s", soname)
-      if soname in filenames_by_soname:
-        print "%s is provided by the package itself" % soname
-      elif soname in lines_by_soname:
-        print ("%s is provided by %s and required by:" 
-               % (soname,
-                  pkgs_by_filename[soname]))
-        filename_lines = " ".join(sorted(binaries_by_soname[soname]))
-        for line in textwrap.wrap(filename_lines, 70):
-          print " ", line
-      else:
-        print ("%s is required by %s, but we don't know what provides it."
-               % (soname, binaries_by_soname[soname]))
-        for binary in binaries_by_soname[soname]:
-          binaries_with_missing_sonames.add(binary)
-        if soname in checkpkg.ALLOWED_ORPHAN_SONAMES:
-          print "However, it's a whitelisted soname."
-        else:
-          pass
-          # The error checking needs to be unified: done in one place only.
-          # errors.append(
-          #     checkpkg.CheckpkgTag(
-          #       "%s is required by %s, but "
-          #       "we don't know what provides it."
-          #       % (soname, binaries_by_soname[soname])))
-    if binaries_with_missing_sonames:
-      print "The following are binaries with missing sonames:"
-      binary_lines = " ".join(sorted(binaries_with_missing_sonames))
-      for line in textwrap.wrap(binary_lines, 70):
-        print " ", line
-    print
-
-  dependent_pkgs = {}
-  for checker in pkgs_data:
-    pkgname = checker["basic_stats"]["pkgname"]
-    declared_dependencies = dict(checker["depends"])
-    missing_deps, surplus_deps, orphan_sonames = checkpkg.AnalyzeDependencies(
-        pkgname,
-        declared_dependencies,
-        binaries_by_pkgname,
-        needed_sonames_by_binary,
-        pkgs_by_filename,
-        filenames_by_soname,
-        pkg_by_any_filename)
-    namespace = {
-        "pkgname": pkgname,
-        "missing_deps": missing_deps,
-        "surplus_deps": surplus_deps,
-        "orphan_sonames": orphan_sonames,
-    }
-    t = Template.Template(checkpkg.REPORT_TMPL, searchList=[namespace])
-    print unicode(t)
-
-    for soname in orphan_sonames:
-      errors.append(
-          checkpkg.CheckpkgTag(
-            pkgname,
-            "orphan-soname",
-            soname))
-    for missing_dep in missing_deps:
-      errors.append(
-          checkpkg.CheckpkgTag(
-            pkgname,
-            "missing-dependency",
-            missing_dep))
-  return errors
-
-
-def main():
-  options, args = checkpkg.GetOptions()
-  md5sums = args
-  # CheckpkgManager class abstracts away things such as the collection of
-  # results.
-  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
-                                           options.stats_basedir,
-                                           md5sums,
-                                           options.debug)
-
-  check_manager.RegisterSetCheck(CheckSharedLibraryConsistency)
-
-  exit_code, screen_report, tags_report = check_manager.Run()
-  f = open(options.output, "w")
-  f.write(tags_report)
-  f.close()
-  print screen_report.strip()
-  sys.exit(exit_code)
-
-
-if __name__ == '__main__':
-  main()
-
-# vim:set sw=2 ts=2 sts=2 expandtab:

Copied: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-libs.py (from rev 9127, csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-libs.py)
===================================================================
--- csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-libs.py	                        (rev 0)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-libs.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -0,0 +1,185 @@
+#!/opt/csw/bin/python2.6
+#
+# $Id$
+
+"""A check for dependencies between shared libraries.
+This is currently more of a prototype than a mature program, but it has some
+unit tests and it appears to be working.  The main problem is that it's not
+divided into smaller testable sections.
+"""
+
+import os
+import os.path
+import copy
+import re
+import subprocess
+import logging
+import sys
+import textwrap
+from Cheetah import Template
+
+CHECKPKG_MODULE_NAME = "shared library linking consistency"
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+             "..", "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+import opencsw
+
+def CheckSharedLibraryConsistency(pkgs_data, debug):
+  ws_re = re.compile(r"\s+")
+  result_ok = True
+  errors = []
+  binaries = []
+  binaries_by_pkgname = {}
+  sonames_by_pkgname = {}
+  pkg_by_any_filename = {}
+  needed_sonames_by_binary = {}
+  filenames_by_soname = {}
+  for pkg_data in pkgs_data:
+    binaries_base = [os.path.basename(x) for x in pkg_data["binaries"]]
+    pkgname = pkg_data["basic_stats"]["pkgname"]
+    binaries_by_pkgname[pkgname] = binaries_base
+    binaries.extend(pkg_data["binaries"])
+    for filename in pkg_data["all_filenames"]:
+      pkg_by_any_filename[filename] = pkgname
+    for binary_data in pkg_data["binaries_dump_info"]:
+      binary_base_name = os.path.basename(binary_data["base_name"])
+      needed_sonames_by_binary[binary_base_name] = binary_data
+      filenames_by_soname[binary_data[checkpkg.SONAME]] = binary_base_name
+    
+  # Making the binaries unique
+  binaries = set(binaries)
+  isalist = pkg_data["isalist"]
+
+  # Building indexes by soname to simplify further processing
+  # These are indexes "by soname".
+  (needed_sonames,
+   binaries_by_soname,
+   runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
+       needed_sonames_by_binary)
+
+  pkgmap = checkpkg.SystemPkgmap()
+  logging.debug("Determining the soname-package relationships.")
+  # lines by soname is an equivalent of $EXTRACTDIR/shortcatalog
+  runpath_data_by_soname = {}
+  for soname in needed_sonames:
+    runpath_data_by_soname[soname] = pkgmap.GetPkgmapLineByBasename(soname)
+  lines_by_soname = checkpkg.GetLinesBySoname(
+      runpath_data_by_soname, needed_sonames, runpath_by_needed_soname, isalist)
+
+  # Creating a map from files to packages.
+  pkgs_by_filename = {}
+  for soname, line in lines_by_soname.iteritems():
+    # TODO: Find all the packages, not just the last field.
+    fields = re.split(ws_re, line.strip())
+    # For now, we'll assume that the last field is the package.
+    pkgname = fields[-1]
+    pkgs_by_filename[soname] = pkgname
+
+  # A shared object dependency/provisioning report, plus checking.
+  #
+  # This section is somewhat overlapping with checkpkg.AnalyzeDependencies(),
+  # it has a different purpose: it reports the relationships between shared
+  # libraries, binaries using them and packages providing them.  Ideally, the
+  # same bit of code would do both checking and reporting.
+  #
+  # TODO: Rewrite this using cheetah templates
+  if debug and needed_sonames:
+    print "Analysis of sonames needed by the package set:"
+    binaries_with_missing_sonames = set([])
+    for soname in needed_sonames:
+      logging.debug("Analyzing: %s", soname)
+      if soname in filenames_by_soname:
+        print "%s is provided by the package itself" % soname
+      elif soname in lines_by_soname:
+        print ("%s is provided by %s and required by:" 
+               % (soname,
+                  pkgs_by_filename[soname]))
+        filename_lines = " ".join(sorted(binaries_by_soname[soname]))
+        for line in textwrap.wrap(filename_lines, 70):
+          print " ", line
+      else:
+        print ("%s is required by %s, but we don't know what provides it."
+               % (soname, binaries_by_soname[soname]))
+        for binary in binaries_by_soname[soname]:
+          binaries_with_missing_sonames.add(binary)
+        if soname in checkpkg.ALLOWED_ORPHAN_SONAMES:
+          print "However, it's a whitelisted soname."
+        else:
+          pass
+          # The error checking needs to be unified: done in one place only.
+          # errors.append(
+          #     checkpkg.CheckpkgTag(
+          #       "%s is required by %s, but "
+          #       "we don't know what provides it."
+          #       % (soname, binaries_by_soname[soname])))
+    if binaries_with_missing_sonames:
+      print "The following are binaries with missing sonames:"
+      binary_lines = " ".join(sorted(binaries_with_missing_sonames))
+      for line in textwrap.wrap(binary_lines, 70):
+        print " ", line
+    print
+
+  dependent_pkgs = {}
+  for checker in pkgs_data:
+    pkgname = checker["basic_stats"]["pkgname"]
+    declared_dependencies = dict(checker["depends"])
+    missing_deps, surplus_deps, orphan_sonames = checkpkg.AnalyzeDependencies(
+        pkgname,
+        declared_dependencies,
+        binaries_by_pkgname,
+        needed_sonames_by_binary,
+        pkgs_by_filename,
+        filenames_by_soname,
+        pkg_by_any_filename)
+    namespace = {
+        "pkgname": pkgname,
+        "missing_deps": missing_deps,
+        "surplus_deps": surplus_deps,
+        "orphan_sonames": orphan_sonames,
+    }
+    t = Template.Template(checkpkg.REPORT_TMPL, searchList=[namespace])
+    print unicode(t)
+
+    for soname in orphan_sonames:
+      errors.append(
+          checkpkg.CheckpkgTag(
+            pkgname,
+            "orphan-soname",
+            soname))
+    for missing_dep in missing_deps:
+      errors.append(
+          checkpkg.CheckpkgTag(
+            pkgname,
+            "missing-dependency",
+            missing_dep))
+  return errors
+
+
+def main():
+  options, args = checkpkg.GetOptions()
+  md5sums = args
+  # CheckpkgManager class abstracts away things such as the collection of
+  # results.
+  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
+                                           options.stats_basedir,
+                                           md5sums,
+                                           options.debug)
+
+  check_manager.RegisterSetCheck(CheckSharedLibraryConsistency)
+
+  exit_code, screen_report, tags_report = check_manager.Run()
+  f = open(options.output, "w")
+  f.write(tags_report)
+  f.close()
+  print screen_report.strip()
+  sys.exit(exit_code)
+
+
+if __name__ == '__main__':
+  main()
+
+# vim:set sw=2 ts=2 sts=2 expandtab:

Deleted: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-license.py
===================================================================
--- csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-license.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-license.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,59 +0,0 @@
-#!/opt/csw/bin/python2.6
-# $Id$
-
-"""Checks for the existence of the license file."""
-
-import logging
-import os.path
-import sys
-
-CHECKPKG_MODULE_NAME = "license presence"
-
-# The following bit of code sets the correct path to Python libraries
-# distributed with GAR.
-path_list = [os.path.dirname(__file__),
-             "..", "..", "lib", "python"]
-sys.path.append(os.path.join(*path_list))
-import checkpkg
-import opencsw
-
-LICENSE_TMPL = "/opt/csw/share/doc/%s/license"
-
-def CheckLicenseFile(pkg_data, debug):
-  """Checks for the presence of the license file."""
-  errors = []
-  pkgmap = pkg_data["pkgmap"]
-  catalogname = pkg_data["basic_stats"]["catalogname"]
-  license_path = LICENSE_TMPL % catalogname
-  pkgmap_paths = [x["path"] for x in pkgmap]
-  if license_path not in pkgmap_paths:
-    errors.append(
-        checkpkg.CheckpkgTag(
-          pkg_data["basic_stats"]["pkgname"],
-          "license-missing",
-          msg="See http://sourceforge.net/apps/trac/gar/wiki/CopyRight"))
-  return errors
-
-
-def main():
-  options, args = checkpkg.GetOptions()
-  md5sums = args
-  # CheckpkgManager class abstracts away things such as the collection of
-  # results.
-  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
-                                           options.stats_basedir,
-                                           md5sums,
-                                           options.debug)
-  # Registering functions defined above.
-  check_manager.RegisterIndividualCheck(CheckLicenseFile)
-  # Running the checks, reporting and exiting.
-  exit_code, screen_report, tags_report = check_manager.Run()
-  f = open(options.output, "w")
-  f.write(tags_report)
-  f.close()
-  print screen_report.strip()
-  sys.exit(exit_code)
-
-
-if __name__ == '__main__':
-  main()

Copied: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-license.py (from rev 9127, csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-license.py)
===================================================================
--- csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-license.py	                        (rev 0)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-license.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -0,0 +1,59 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+"""Checks for the existence of the license file."""
+
+import logging
+import os.path
+import sys
+
+CHECKPKG_MODULE_NAME = "license presence"
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+             "..", "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+import opencsw
+
+LICENSE_TMPL = "/opt/csw/share/doc/%s/license"
+
+def CheckLicenseFile(pkg_data, debug):
+  """Checks for the presence of the license file."""
+  errors = []
+  pkgmap = pkg_data["pkgmap"]
+  catalogname = pkg_data["basic_stats"]["catalogname"]
+  license_path = LICENSE_TMPL % catalogname
+  pkgmap_paths = [x["path"] for x in pkgmap]
+  if license_path not in pkgmap_paths:
+    errors.append(
+        checkpkg.CheckpkgTag(
+          pkg_data["basic_stats"]["pkgname"],
+          "license-missing",
+          msg="See http://sourceforge.net/apps/trac/gar/wiki/CopyRight"))
+  return errors
+
+
+def main():
+  options, args = checkpkg.GetOptions()
+  md5sums = args
+  # CheckpkgManager class abstracts away things such as the collection of
+  # results.
+  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
+                                           options.stats_basedir,
+                                           md5sums,
+                                           options.debug)
+  # Registering functions defined above.
+  check_manager.RegisterIndividualCheck(CheckLicenseFile)
+  # Running the checks, reporting and exiting.
+  exit_code, screen_report, tags_report = check_manager.Run()
+  f = open(options.output, "w")
+  f.write(tags_report)
+  f.close()
+  print screen_report.strip()
+  sys.exit(exit_code)
+
+
+if __name__ == '__main__':
+  main()

Deleted: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-missing-symbols.py
===================================================================
--- csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-missing-symbols.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-missing-symbols.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,47 +0,0 @@
-#!/opt/csw/bin/python2.6
-# $Id$
-
-"""Check for missing symbols in binaries.
-
-http://sourceforge.net/tracker/?func=detail&aid=2939416&group_id=229205&atid=1075770
-"""
-
-import os.path
-import re
-import sys
-import subprocess
-
-CHECKPKG_MODULE_NAME = "missing symbols"
-
-# The following bit of code sets the correct path to Python libraries
-# distributed with GAR.
-path_list = [os.path.dirname(__file__),
-             "..", "..", "lib", "python"]
-sys.path.append(os.path.join(*path_list))
-import checkpkg
-import package_checks_old
-
-# Defining checking functions.
-
-def main():
-  options, args = checkpkg.GetOptions()
-  md5sums = args
-  # CheckpkgManager class abstracts away things such as the collection of
-  # results.
-  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
-                                           options.stats_basedir,
-                                           md5sums,
-                                           options.debug)
-  # Registering functions defined above.
-  check_manager.RegisterSetCheck(package_checks_old.CheckForMissingSymbols)
-  # Running the checks, reporting and exiting.
-  exit_code, screen_report, tags_report = check_manager.Run()
-  f = open(options.output, "w")
-  f.write(tags_report)
-  f.close()
-  print screen_report.strip()
-  sys.exit(exit_code)
-
-
-if __name__ == '__main__':
-  main()

Copied: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-missing-symbols.py (from rev 9127, csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-missing-symbols.py)
===================================================================
--- csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-missing-symbols.py	                        (rev 0)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-missing-symbols.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -0,0 +1,47 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+"""Check for missing symbols in binaries.
+
+http://sourceforge.net/tracker/?func=detail&aid=2939416&group_id=229205&atid=1075770
+"""
+
+import os.path
+import re
+import sys
+import subprocess
+
+CHECKPKG_MODULE_NAME = "missing symbols"
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+             "..", "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+import package_checks_old
+
+# Defining checking functions.
+
+def main():
+  options, args = checkpkg.GetOptions()
+  md5sums = args
+  # CheckpkgManager class abstracts away things such as the collection of
+  # results.
+  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
+                                           options.stats_basedir,
+                                           md5sums,
+                                           options.debug)
+  # Registering functions defined above.
+  check_manager.RegisterSetCheck(package_checks_old.CheckForMissingSymbols)
+  # Running the checks, reporting and exiting.
+  exit_code, screen_report, tags_report = check_manager.Run()
+  f = open(options.output, "w")
+  f.write(tags_report)
+  f.close()
+  print screen_report.strip()
+  sys.exit(exit_code)
+
+
+if __name__ == '__main__':
+  main()

Deleted: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-obsolete-deps.py
===================================================================
--- csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-obsolete-deps.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-obsolete-deps.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,74 +0,0 @@
-#!/opt/csw/bin/python2.6
-# $Id$
-
-"""Makes sure that obsolete packages are not added as dependencies.
-"""
-
-import logging
-import os.path
-import sys
-
-CHECKPKG_MODULE_NAME = "obsolete dependencies"
-
-# The following bit of code sets the correct path to Python libraries
-# distributed with GAR.
-path_list = [os.path.dirname(__file__),
-             "..", "..", "lib", "python"]
-sys.path.append(os.path.join(*path_list))
-import checkpkg
-
-OBSOLETE_DEPS = {
-    # "CSWfoo": {
-    #   "hint": "Do this...",
-    #   "url": "http://www.opencsw.org/bugtrack/view.php?id=..."
-    # },
-    "CSWpython-rt": {
-      "hint": "CSWpython-rt is deprecated, use CSWpython instead.",
-      "url": "http://www.opencsw.org/bugtrack/view.php?id=4031"
-    },
-}
-
-def CheckObsoleteDeps(pkg_data, debug):
-  """Checks for obsolete dependencies."""
-  errors = []
-  deps = set(pkg_data["depends"])
-  obsolete_pkg_deps = deps.intersection(set(OBSOLETE_DEPS))
-  if obsolete_pkg_deps:
-    for obsolete_pkg in obsolete_pkg_deps:
-      msg = ""
-      if "hint" in OBSOLETE_DEPS[obsolete_pkg]:
-        msg += "Hint: %s" % OBSOLETE_DEPS[obsolete_pkg]["hint"]
-      if "url" in OBSOLETE_DEPS[obsolete_pkg]:
-        if msg:
-          msg += ", "
-        msg += "URL: %s" % OBSOLETE_DEPS[obsolete_pkg]["url"]
-      if not msg:
-        msg = None
-      errors.append(
-          checkpkg.CheckpkgTag(
-    	      pkg_data["basic_stats"]["pkgname"],
-            "obsolete-dependency", obsolete_pkg, msg=msg))
-  return errors
-
-
-def main():
-  options, args = checkpkg.GetOptions()
-  md5sums = args
-  # CheckpkgManager class abstracts away things such as the collection of
-  # results.
-  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
-                                           options.stats_basedir,
-                                           md5sums,
-                                           options.debug)
-  check_manager.RegisterIndividualCheck(CheckObsoleteDeps)
-  # Running the checks, reporting and exiting.
-  exit_code, screen_report, tags_report = check_manager.Run()
-  f = open(options.output, "w")
-  f.write(tags_report)
-  f.close()
-  print screen_report.strip()
-  sys.exit(exit_code)
-
-
-if __name__ == '__main__':
-  main()

Copied: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-obsolete-deps.py (from rev 9127, csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-obsolete-deps.py)
===================================================================
--- csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-obsolete-deps.py	                        (rev 0)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-obsolete-deps.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -0,0 +1,74 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+"""Makes sure that obsolete packages are not added as dependencies.
+"""
+
+import logging
+import os.path
+import sys
+
+CHECKPKG_MODULE_NAME = "obsolete dependencies"
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+             "..", "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+
+OBSOLETE_DEPS = {
+    # "CSWfoo": {
+    #   "hint": "Do this...",
+    #   "url": "http://www.opencsw.org/bugtrack/view.php?id=..."
+    # },
+    "CSWpython-rt": {
+      "hint": "CSWpython-rt is deprecated, use CSWpython instead.",
+      "url": "http://www.opencsw.org/bugtrack/view.php?id=4031"
+    },
+}
+
+def CheckObsoleteDeps(pkg_data, debug):
+  """Checks for obsolete dependencies."""
+  errors = []
+  deps = set(pkg_data["depends"])
+  obsolete_pkg_deps = deps.intersection(set(OBSOLETE_DEPS))
+  if obsolete_pkg_deps:
+    for obsolete_pkg in obsolete_pkg_deps:
+      msg = ""
+      if "hint" in OBSOLETE_DEPS[obsolete_pkg]:
+        msg += "Hint: %s" % OBSOLETE_DEPS[obsolete_pkg]["hint"]
+      if "url" in OBSOLETE_DEPS[obsolete_pkg]:
+        if msg:
+          msg += ", "
+        msg += "URL: %s" % OBSOLETE_DEPS[obsolete_pkg]["url"]
+      if not msg:
+        msg = None
+      errors.append(
+          checkpkg.CheckpkgTag(
+    	      pkg_data["basic_stats"]["pkgname"],
+            "obsolete-dependency", obsolete_pkg, msg=msg))
+  return errors
+
+
+def main():
+  options, args = checkpkg.GetOptions()
+  md5sums = args
+  # CheckpkgManager class abstracts away things such as the collection of
+  # results.
+  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
+                                           options.stats_basedir,
+                                           md5sums,
+                                           options.debug)
+  check_manager.RegisterIndividualCheck(CheckObsoleteDeps)
+  # Running the checks, reporting and exiting.
+  exit_code, screen_report, tags_report = check_manager.Run()
+  f = open(options.output, "w")
+  f.write(tags_report)
+  f.close()
+  print screen_report.strip()
+  sys.exit(exit_code)
+
+
+if __name__ == '__main__':
+  main()

Deleted: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-you-can-write-your-own.py
===================================================================
--- csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-you-can-write-your-own.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-you-can-write-your-own.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -1,84 +0,0 @@
-#!/opt/csw/bin/python2.6
-# $Id$
-
-"""This is a dummy module. You can use it as a boilerplate for your own modules.
-
-Copy it and modify.
-"""
-
-import os.path
-import sys
-
-CHECKPKG_MODULE_NAME = "a template of a checkpkg module"
-
-# The following bit of code sets the correct path to Python libraries
-# distributed with GAR.
-path_list = [os.path.dirname(__file__),
-             "..", "..", "lib", "python"]
-sys.path.append(os.path.join(*path_list))
-import checkpkg
-
-# Defining the checking functions.  They come in two flavors: individual
-# package checks and set checks.
-
-def MyCheckForAsinglePackage(pkg_data, debug):
-  """Checks an individual package.
-  
-  Gets a DirctoryFormatPackage as an argument, and returns a list of errors.
-
-  Errors should be a list of checkpkg.CheckpkgTag objects:
-  errors.append(checkpkg.CheckpkgTag(pkg.pkgname, "tag-name"))
-
-  You can also add a parameter:
-  errors.append(checkpkg.CheckpkgTag(pkg.pkgname, "tag-name", "/opt/csw/bin/problem"))
-  """
-  errors = []
-  # Checking code for an individual package goes here.  See the
-  # DirectoryFormatPackage class in lib/python/opencsw.py for the available
-  # APIs.
-
-  # Here's how to report an error:
-  something_is_wrong = False
-  if something_is_wrong:
-    errors.append(checkpkg.CheckpkgTag(
-      pkg_data["basic_stats"]["pkgname"],
-      "example-problem", "thing"))
-  return errors
-
-
-def MyCheckForAsetOfPackages(pkgs_data, debug):
-  """Checks a set of packages.
-
-  Sometimes individual checks aren't enough. If you need to write code which
-  needs to examine multiple packages at the same time, use this function.
-
-  Gets a list of packages, returns a list of errors.
-  """
-  errors = []
-  # Checking code goes here.
-  return errors
-
-
-def main():
-  options, args = checkpkg.GetOptions()
-  md5sums = args
-  # CheckpkgManager class abstracts away things such as the collection of
-  # results.
-  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
-                                           options.stats_basedir,
-                                           md5sums,
-                                           options.debug)
-  # Registering functions defined above.
-  check_manager.RegisterIndividualCheck(MyCheckForAsinglePackage)
-  check_manager.RegisterSetCheck(MyCheckForAsetOfPackages)
-  # Running the checks, reporting and exiting.
-  exit_code, screen_report, tags_report = check_manager.Run()
-  f = open(options.output, "w")
-  f.write(tags_report)
-  f.close()
-  print screen_report.strip()
-  sys.exit(exit_code)
-
-
-if __name__ == '__main__':
-  main()

Copied: csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-you-can-write-your-own.py (from rev 9127, csw/mgar/gar/v2/lib/checkpkg.d/checkpkg-you-can-write-your-own.py)
===================================================================
--- csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-you-can-write-your-own.py	                        (rev 0)
+++ csw/mgar/gar/v2-git/lib/checkpkg.d/checkpkg-you-can-write-your-own.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -0,0 +1,84 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+"""This is a dummy module. You can use it as a boilerplate for your own modules.
+
+Copy it and modify.
+"""
+
+import os.path
+import sys
+
+CHECKPKG_MODULE_NAME = "a template of a checkpkg module"
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+             "..", "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+
+# Defining the checking functions.  They come in two flavors: individual
+# package checks and set checks.
+
+def MyCheckForAsinglePackage(pkg_data, debug):
+  """Checks an individual package.
+  
+  Gets a DirctoryFormatPackage as an argument, and returns a list of errors.
+
+  Errors should be a list of checkpkg.CheckpkgTag objects:
+  errors.append(checkpkg.CheckpkgTag(pkg.pkgname, "tag-name"))
+
+  You can also add a parameter:
+  errors.append(checkpkg.CheckpkgTag(pkg.pkgname, "tag-name", "/opt/csw/bin/problem"))
+  """
+  errors = []
+  # Checking code for an individual package goes here.  See the
+  # DirectoryFormatPackage class in lib/python/opencsw.py for the available
+  # APIs.
+
+  # Here's how to report an error:
+  something_is_wrong = False
+  if something_is_wrong:
+    errors.append(checkpkg.CheckpkgTag(
+      pkg_data["basic_stats"]["pkgname"],
+      "example-problem", "thing"))
+  return errors
+
+
+def MyCheckForAsetOfPackages(pkgs_data, debug):
+  """Checks a set of packages.
+
+  Sometimes individual checks aren't enough. If you need to write code which
+  needs to examine multiple packages at the same time, use this function.
+
+  Gets a list of packages, returns a list of errors.
+  """
+  errors = []
+  # Checking code goes here.
+  return errors
+
+
+def main():
+  options, args = checkpkg.GetOptions()
+  md5sums = args
+  # CheckpkgManager class abstracts away things such as the collection of
+  # results.
+  check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
+                                           options.stats_basedir,
+                                           md5sums,
+                                           options.debug)
+  # Registering functions defined above.
+  check_manager.RegisterIndividualCheck(MyCheckForAsinglePackage)
+  check_manager.RegisterSetCheck(MyCheckForAsetOfPackages)
+  # Running the checks, reporting and exiting.
+  exit_code, screen_report, tags_report = check_manager.Run()
+  f = open(options.output, "w")
+  f.write(tags_report)
+  f.close()
+  print screen_report.strip()
+  sys.exit(exit_code)
+
+
+if __name__ == '__main__':
+  main()

Modified: csw/mgar/gar/v2-git/lib/python/checkpkg.py
===================================================================
--- csw/mgar/gar/v2-git/lib/python/checkpkg.py	2010-03-13 08:35:34 UTC (rev 9127)
+++ csw/mgar/gar/v2-git/lib/python/checkpkg.py	2010-03-13 09:55:32 UTC (rev 9128)
@@ -15,9 +15,11 @@
 import socket
 import sqlite3
 import subprocess
+import textwrap
 import yaml
 from Cheetah import Template
 import opencsw
+import package_checks
 
 SYSTEM_PKGMAP = "/var/sadm/install/contents"
 WS_RE = re.compile(r"\s+")
@@ -29,6 +31,8 @@
 DO_NOT_REPORT_MISSING = set([])
 DO_NOT_REPORT_MISSING_RE = [r"SUNW.*", r"\*SUNW.*"]
 DUMP_BIN = "/usr/ccs/bin/dump"
+PSTAMP_RE = r"(?P<username>\w)+@(?P<hostname>[\w\.]+)-(?P<timestamp>\d+)"
+DESCRIPTION_RE = r"^([\S]+) - (.*)$"
 
 SYSTEM_SYMLINKS = (
     ("/opt/csw/bdb4",     ["/opt/csw/bdb42"]),
@@ -36,6 +40,8 @@
     ("/opt/csw/lib/i386", ["/opt/csw/lib"]),
 )
 INSTALL_CONTENTS_AVG_LINE_LENGTH = 102.09710677919261
+DB_SCHEMA_VERSION = 2L
+PACKAGE_STATS_VERSION = 2L
 
 # This shared library is present on Solaris 10 on amd64, but it's missing on
 # Solaris 8 on i386.  It's okay if it's missing.
@@ -91,6 +97,9 @@
 # Tags reported by $name module
 #for $pkgname in $errors
 #for $tag in $errors[$pkgname]
+#if $tag.msg
+$textwrap.fill($tag.msg, 70, initial_indent="# ", subsequent_indent="# ")
+#end if
 $pkgname: ${tag.tag_name}#if $tag.tag_info# $tag.tag_info#end if#
 #end for
 #end for
@@ -110,6 +119,10 @@
   pass
 
 
+class StdoutSyntaxError(Error):
+  pass
+
+
 def GetOptions():
   parser = optparse.OptionParser()
   parser.add_option("-b", dest="stats_basedir",
@@ -141,13 +154,33 @@
   return unicode(t)
 
 
+def ExtractDescription(pkginfo):
+  desc_re = re.compile(DESCRIPTION_RE)
+  m = re.match(desc_re, pkginfo["NAME"])
+  return m.group(2) if m else None
+
+
+def ExtractMaintainerName(pkginfo):
+  maint_re = re.compile("^.*for CSW by (.*)$")
+  m = re.match(maint_re, pkginfo["VENDOR"])
+  return m.group(1) if m else None
+
+
+def ExtractBuildUsername(pkginfo):
+  m = re.match(PSTAMP_RE, pkginfo["PSTAMP"])
+  if m:
+    return m.group("username")
+  else:
+    return None
+
+
 class SystemPkgmap(object):
   """A class to hold and manipulate the /var/sadm/install/contents file.
 
   TODO: Implement timestamp checking and refreshing the cache.
   """
-  
-  STOP_PKGS = ["SUNWbcp", "SUNWowbcp", "SUNWucb"] 
+
+  STOP_PKGS = ["SUNWbcp", "SUNWowbcp", "SUNWucb"]
   CHECKPKG_DIR = ".checkpkg"
   SQLITE3_DBNAME_TMPL = "var-sadm-install-contents-cache-%s"
 
@@ -162,20 +195,36 @@
                                 self.SQLITE3_DBNAME_TMPL % self.fqdn)
     self.file_mtime = None
     self.cache_mtime = None
+    self.initialized = False
+
+  def _LazyInitializeDatabase(self):
+    if not self.initialized:
+      self.InitializeDatabase()
+
+  def InitializeDatabase(self):
     if os.path.exists(self.db_path):
       logging.debug("Connecting to the %s database.", self.db_path)
       self.conn = sqlite3.connect(self.db_path)
+      if not self.IsDatabaseGoodSchema():
+        logging.warning("Old database schema detected. Dropping tables.")
+        self.PurgeDatabase(drop_tables=True)
+        self.CreateTables()
       if not self.IsDatabaseUpToDate():
         logging.warning("Rebuilding the package cache, can take a few minutes.")
         self.PurgeDatabase()
         self.PopulateDatabase()
     else:
-      print "Building a cache of /var/sadm/install/contents."
+      print "Building a cache of %s." % SYSTEM_PKGMAP
       print "The cache will be kept in %s." % self.db_path
       if not os.path.exists(self.checkpkg_dir):
         logging.debug("Creating %s", self.checkpkg_dir)
         os.mkdir(self.checkpkg_dir)
       self.conn = sqlite3.connect(self.db_path)
+      self.CreateTables()
+      self.PopulateDatabase()
+    self.initialized = True
+
+  def CreateTables(self):
       c = self.conn.cursor()
       c.execute("""
           CREATE TABLE systempkgmap (
@@ -190,24 +239,24 @@
           CREATE TABLE config (
             key VARCHAR(255) PRIMARY KEY,
             float_value FLOAT,
+            int_value INTEGER,
             str_value VARCHAR(255)
           );
       """)
-      self.PopulateDatabase()
+      c.execute("""
+          CREATE TABLE packages (
+            pkgname VARCHAR(255) PRIMARY KEY,
+            pkg_desc VARCHAR(255)
+          );
+      """)
 
-  def SymlinkDuringInstallation(self, p):
-    """Emulates the effect of some symlinks present during installations."""
-    p = p.replace("/opt/csw/lib/i386", "/opt/csw/lib")
-
   def PopulateDatabase(self):
     """Imports data into the database.
 
     Original bit of code from checkpkg:
-    
     egrep -v 'SUNWbcp|SUNWowbcp|SUNWucb' /var/sadm/install/contents |
         fgrep -f $EXTRACTDIR/liblist >$EXTRACTDIR/shortcatalog
     """
-
     contents_length = os.stat(SYSTEM_PKGMAP).st_size
     estimated_lines = contents_length / INSTALL_CONTENTS_AVG_LINE_LENGTH
     system_pkgmap_fd = open(SYSTEM_PKGMAP, "r")
@@ -219,6 +268,7 @@
     print "Processing %s" % SYSTEM_PKGMAP
     c = self.conn.cursor()
     count = itertools.count()
+    sql = "INSERT INTO systempkgmap (basename, path, line) VALUES (?, ?, ?);"
     for line in system_pkgmap_fd:
       i = count.next()
       if not i % 1000:
@@ -230,15 +280,40 @@
       fields = re.split(WS_RE, line)
       pkgmap_entry_path = fields[0].split("=")[0]
       pkgmap_entry_dir, pkgmap_entry_base_name = os.path.split(pkgmap_entry_path)
-      sql = "INSERT INTO systempkgmap (basename, path, line) VALUES (?, ?, ?);"
       c.execute(sql, (pkgmap_entry_base_name, pkgmap_entry_dir, line.strip()))
     print "\rAll lines of %s were processed." % SYSTEM_PKGMAP
     print "Creating the main database index."
     sql = "CREATE INDEX basename_idx ON systempkgmap(basename);"
     c.execute(sql)
+    self.PopulatePackagesTable()
     self.SetDatabaseMtime()
+    self.SetDatabaseSchemaVersion()
     self.conn.commit()
 
+  def _ParsePkginfoLine(self, line):
+    fields = re.split(WS_RE, line)
+    pkgname = fields[1]
+    pkg_desc = u" ".join(fields[2:])
+    return pkgname, pkg_desc
+
+  def PopulatePackagesTable(self):
+    args = ["pkginfo"]
+    pkginfo_proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+    stdout, stderr = pkginfo_proc.communicate()
+    ret = pkginfo_proc.wait()
+    c = self.conn.cursor()
+    sql = """
+    INSERT INTO packages (pkgname, pkg_desc)
+    VALUES (?, ?);
+    """
+    for line in stdout.splitlines():
+      pkgname, pkg_desc = self._ParsePkginfoLine(line)
+      try:
+        c.execute(sql, [pkgname, pkg_desc])
+      except sqlite3.IntegrityError, e:
+        logging.warn("pkgname %s throws an sqlite3.IntegrityError: %s",
+                     repr(pkgname), e)
+
   def SetDatabaseMtime(self):
     c = self.conn.cursor()
     sql = "DELETE FROM config WHERE key = ?;"
@@ -251,7 +326,17 @@
     """
     c.execute(sql, [CONFIG_MTIME, mtime])
 
+  def SetDatabaseSchemaVersion(self):
+    sql = """
+    INSERT INTO config (key, int_value)
+    VALUES (?, ?);
+    """
+    c = self.conn.cursor()
+    c.execute(sql, ["db_schema_version", DB_SCHEMA_VERSION])
+    logging.debug("Setting db_schema_version to %s", DB_SCHEMA_VERSION)
+
   def GetPkgmapLineByBasename(self, filename):
+    self._LazyInitializeDatabase()
     if filename in self.cache:
       return self.cache[filename]
     sql = "SELECT path, line FROM systempkgmap WHERE basename = ?;"
@@ -287,26 +372,67 @@
       self.file_mtime = stat_data.st_mtime
     return self.file_mtime
 
+  def GetDatabaseSchemaVersion(self):
+    sql = """
+    SELECT int_value FROM config
+    WHERE key = ?;
+    """
+    c = self.conn.cursor()
+    schema_on_disk = 1L
+    try:
+      c.execute(sql, ["db_schema_version"])
+      for row in c:
+        schema_on_disk = row[0]
+    except sqlite3.OperationalError, e:
+      # : no such column: int_value
+      # The first versions of the database did not
+      # have the int_value field.
+      if re.search(r"int_value", str(e)):
+        # We assume it's the first schema version.
+        logging.debug("sqlite3.OperationalError, %s: guessing it's 1.", e)
+      else:
+        raise
+    return schema_on_disk
+
+  def IsDatabaseGoodSchema(self):
+    good_version = self.GetDatabaseSchemaVersion() >= DB_SCHEMA_VERSION
+    return good_version
+
   def IsDatabaseUpToDate(self):
     f_mtime = self.GetFileMtime()
     d_mtime = self.GetDatabaseMtime()
     logging.debug("f_mtime %s, d_time: %s", f_mtime, d_mtime)
-    return self.GetFileMtime() <= self.GetDatabaseMtime()
+    fresh = self.GetFileMtime() <= self.GetDatabaseMtime()
+    good_version = self.GetDatabaseSchemaVersion() >= DB_SCHEMA_VERSION
+    return fresh and good_version
 
-  def PurgeDatabase(self):
+  def SoftDropTable(self, tablename):
     c = self.conn.cursor()
-    logging.info("Dropping the index.")
-    sql = "DROP INDEX basename_idx;"
     try:
-      c.execute(sql)
+      # This doesn't accept placeholders.
+      c.execute("DROP TABLE %s;" % tablename)
     except sqlite3.OperationalError, e:
-      logging.warn(e)
-    logging.info("Deleting all rows from the cache database")
-    sql = "DELETE FROM config;"
-    c.execute(sql)
-    sql = "DELETE FROM systempkgmap;"
-    c.execute(sql)
+      logging.warn("sqlite3.OperationalError: %s", e)
 
+  def PurgeDatabase(self, drop_tables=False):
+    c = self.conn.cursor()
+    if drop_tables:
+      for table_name in ("config", "systempkgmap", "packages"):
+        self.SoftDropTable(table_name)
+    else:
+      logging.info("Dropping the index.")
+      sql = "DROP INDEX basename_idx;"
+      try:
+        c.execute(sql)
+      except sqlite3.OperationalError, e:
+        logging.warn(e)
+      logging.info("Deleting all rows from the cache database")
+      for table in ("config", "systempkgmap", "packages"):
+        try:
+          c.execute("DELETE FROM %s;" % table)
+        except sqlite3.OperationalError, e:
+          logging.warn("sqlite3.OperationalError: %s", e)
+
 def SharedObjectDependencies(pkgname,
                              binaries_by_pkgname,
                              needed_sonames_by_binary,
@@ -316,7 +442,7 @@
   """This is one of the more obscure and more important pieces of code.
 
   I tried to make it simpler, but given that the operations here involve
-  whole sets of packages, it's not easy.
+  whole sets of packages, it's not easy to simplify.
   """
   so_dependencies = set()
   orphan_sonames = set()
@@ -474,7 +600,9 @@
   return runpath
 
 
-def GetLinesBySoname(pkgmap, needed_sonames, runpath_by_needed_soname, isalist):
+def GetLinesBySoname(runpath_data_by_soname,
+                     needed_sonames,
+                     runpath_by_needed_soname, isalist):
   """Works out which system pkgmap lines correspond to given sonames."""
   lines_by_soname = {}
   for soname in needed_sonames:
@@ -485,11 +613,11 @@
       runpath = SanitizeRunpath(runpath)
       runpath_list = ExpandRunpath(runpath, isalist)
       runpath_list = Emulate64BitSymlinks(runpath_list)
-      soname_runpath_data = pkgmap.GetPkgmapLineByBasename(soname)
       # Emulating the install time symlinks, for instance, if the prototype contains
       # /opt/csw/lib/i386/foo.so.0 and /opt/csw/lib/i386 is a symlink to ".",
-      # the shared library ends up in /opt/csw/lib/foo.so.0 and should be findable even when
-      # RPATH does not contain $ISALIST.
+      # the shared library ends up in /opt/csw/lib/foo.so.0 and should be
+      # findable even when RPATH does not contain $ISALIST.
+      soname_runpath_data = runpath_data_by_soname[soname]
       new_soname_runpath_data = {}
       for p in soname_runpath_data:
         expanded_p_list = Emulate64BitSymlinks([p])
@@ -568,13 +696,31 @@
     self.msg = msg
 
   def __repr__(self):
-    return (u"CheckpkgTag(%s, %s, %s, ...)"
-            % (repr(self.pkgname), repr(self.tag_name), repr(self.tag_info)))
+    return (u"CheckpkgTag(%s, %s, %s, %s)"
+            % (repr(self.pkgname),
+               repr(self.tag_name),
+               repr(self.tag_info),
+               repr(self.msg)))
 
+  def ToGarSyntax(self):
+    msg_lines = []
+    if self.msg:
+      msg_lines.extend(textwrap(self.msg, 70,
+                                initial_indent="# ",
+                                subsequent_indent="# "))
+    if self.tag_info:
+      tag_postfix = "|%s" % self.tag_info.replace(" ", "|")
+    else:
+      tag_postfix = ""
+    msg_lines.append(u"CHECKPKG_OVERRIDES_%s += %s%s"
+                     % (self.pkgname, self.tag_name, tag_postfix))
+    return "\n".join(msg_lines)
 
-class CheckpkgManager(object):
-  """Takes care of calling checking functions"""
 
+
+class CheckpkgManagerBase(object):
+  """Common functions between the older and newer calling functions."""
+
   def __init__(self, name, stats_basedir, md5sum_list, debug=False):
     self.debug = debug
     self.name = name
@@ -585,49 +731,18 @@
     self.set_checks = []
     self.packages = []
 
-  def RegisterIndividualCheck(self, function):
-    self.individual_checks.append(function)
-
-  def RegisterSetCheck(self, function):
-    self.set_checks.append(function)
-
   def GetPackageStatsList(self):
     stats_list = []
     for md5sum in self.md5sum_list:
       stats_list.append(PackageStats(None, self.stats_basedir, md5sum))
     return stats_list
 
-  def GetAllTags(self, packages_data):
-    errors = {}
-    for pkg_data in packages_data:
-      for function in self.individual_checks:
-        all_stats = pkg_data.GetAllStats()
-        errors_for_pkg = function(all_stats, debug=self.debug)
-        if errors_for_pkg:
-          errors[all_stats["basic_stats"]["pkgname"]] = errors_for_pkg
-    # Set checks
-    for function in self.set_checks:
-      set_errors = function([x.GetAllStats() for x in packages_data],
-                            debug=self.debug)
-      if set_errors:
-        # These were generated by a set, but are likely to be bound to specific
-        # packages. We'll try to preserve the package assignments.
-        for tag in set_errors:
-          if tag.pkgname:
-            if not tag.pkgname in errors:
-              errors[tag.pkgname] = []
-            errors[tag.pkgname].append(tag)
-          else:
-            if "package-set" not in errors:
-              errors["package-set"] = []
-            errors["package-set"].append(error)
-    return errors
-
   def FormatReports(self, errors):
     namespace = {
         "name": self.name,
         "errors": errors,
         "debug": self.debug,
+        "textwrap": textwrap,
     }
     screen_t = Template.Template(SCREEN_ERROR_REPORT_TMPL, searchList=[namespace])
     tags_report_t = Template.Template(TAG_REPORT_TMPL, searchList=[namespace])
@@ -647,6 +762,150 @@
     return (exit_code, screen_report, tags_report)
 
 
+class CheckpkgManager(CheckpkgManagerBase):
+  """Takes care of calling checking functions.
+
+  This is an old API as of 2010-02-28.
+  """
+  def RegisterIndividualCheck(self, function):
+    self.individual_checks.append(function)
+
+  def RegisterSetCheck(self, function):
+    self.set_checks.append(function)
+
+  def SetErrorsToDict(self, set_errors, a_dict):
+    # These were generated by a set, but are likely to be bound to specific
+    # packages. We'll try to preserve the package assignments.
+    errors = copy.copy(a_dict)
+    for tag in set_errors:
+      if tag.pkgname:
+        if not tag.pkgname in errors:
+          errors[tag.pkgname] = []
+        errors[tag.pkgname].append(tag)
+      else:
+        if "package-set" not in errors:
+          errors["package-set"] = []
+        errors["package-set"].append(error)
+    return a_dict
+
+  def GetAllTags(self, packages_data):
+    errors = {}
+    for pkg_data in packages_data:
+      for function in self.individual_checks:
+        all_stats = pkg_data.GetAllStats()
+        errors_for_pkg = function(all_stats, debug=self.debug)
+        if errors_for_pkg:
+          errors[all_stats["basic_stats"]["pkgname"]] = errors_for_pkg
+    # Set checks
+    for function in self.set_checks:
+      set_errors = function([x.GetAllStats() for x in packages_data],
+                            debug=self.debug)
+      if set_errors:
+        errors = self.SetErrorsToDict(set_errors, errors)
+    return errors
+
+
+class CheckInterfaceBase(object):
+  """Base class for check proxies.
+
+  It wraps access to the /var/sadm/install/contents cache.
+  """
+
+  def __init__(self, system_pkgmap=None):
+    self.system_pkgmap = system_pkgmap
+    if not self.system_pkgmap:
+      self.system_pkgmap = SystemPkgmap()
+
+
+class IndividualCheckInterface(CheckInterfaceBase):
+  """To be passed to the checking functions.
+
+  Wraps the creation of CheckpkgTag objects.
+  """
+
+  def __init__(self, pkgname, system_pkgmap=None):
+    super(IndividualCheckInterface, self).__init__(system_pkgmap)
+    self.pkgname = pkgname
+    self.errors = []
+
+  def ReportError(self, tag_name, tag_info=None, msg=None):
+    tag = CheckpkgTag(self.pkgname, tag_name, tag_info, msg)
+    self.errors.append(tag)
+
+
+def SetCheckInterface(object):
+  """To be passed to set checking functions."""
+  def __init__(self, system_pkgmap):
+    super(SetCheckInterface, self).__init__(system_pkgmap)
+    self.errors = []
+
+  def ReportError(self, pkgname, tag_name, tag_info=None, msg=None):
+    tag = CheckpkgTag(pkgname, tag_name, tag_info, msg)
+    self.errors.append(tag)
+
+
+class CheckpkgManager2(CheckpkgManagerBase):
+  """The second incarnation of the checkpkg manager.
+
+  Implements the API to be used by checking functions.
+
+  Its purpose is to reduce the amount of boilerplate code and allow for easier
+  unit test writing.
+  """
+  def _RegisterIndividualCheck(self, function):
+    self.individual_checks.append(function)
+
+  def _RegisterSetCheck(self, function):
+    self.set_checks.append(function)
+
+  def _AutoregisterChecks(self):
+    """Autodetects all defined checks."""
+    logging.debug("CheckpkgManager2._AutoregisterChecks()")
+    checkpkg_module = package_checks
+    members = dir(checkpkg_module)
+    for member_name in members:
+      logging.debug("member_name: %s", repr(member_name))
+      member = getattr(checkpkg_module, member_name)
+      if callable(member):
+        if member_name.startswith("Check"):
+          logging.debug("Registering individual check %s", repr(member_name))
+          self._RegisterIndividualCheck(member)
+        elif member_name.startswith("SetCheck"):
+          logging.debug("Registering set check %s", repr(member_name))
+          self._RegisterIndividualCheck(member)
+
+  def GetAllTags(self, packages_data):
+    errors = {}
+    logging_level = logging.INFO
+    if self.debug:
+      logging_level = logging.DEBUG
+    # Individual checks
+    for pkg_data in packages_data:
+      for function in self.individual_checks:
+        all_stats = pkg_data.GetAllStats()
+        pkgname = all_stats["basic_stats"]["pkgname"]
+        check_interface = IndividualCheckInterface(pkgname)
+        logger = logging.getLogger("%s-%s" % (pkgname, function.__name__))
+        logger.debug("Calling %s", function.__name__)
+        function(all_stats, check_interface, logger=logger)
+        if check_interface.errors:
+          errors[pkgname] = check_interface.errors
+    # Set checks
+    for function in self.set_checks:
+      pkgs_data = [x.GetAllStats() for x in packages_data]
+      logger = logging.getLogger("SetCheck-%s" % (function.__name__,))
+      check_interface = SetCheckInterface()
+      logger.debug("Calling %s", function.__name__)
+      function(pkgs_data, check_interface, logger)
+      if check_interface.errors:
+        errors = self.SetErrorsToDict(check_interface.errors, errors)
+    return errors
+
+  def Run(self):
+    self._AutoregisterChecks()
+    return super(CheckpkgManager2, self).Run()
+
+
 def ParseTagLine(line):
   """Parses a line from the tag.${module} file.
 
@@ -681,7 +940,7 @@
 
   def __repr__(self):
     return (u"Override(%s, %s, %s)"
-            % (self.pkgname, self.tag_name, self.tag_info))
+            % (repr(self.pkgname), repr(self.tag_name), repr(self.tag_info)))
 
   def DoesApply(self, tag):
     """Figures out if this override applies to the given tag."""
@@ -697,6 +956,7 @@
     basket_b["tag_name"] = tag.tag_name
     return basket_a == basket_b
 
+
 def ParseOverrideLine(line):
   level_1 = line.split(":")
   if len(level_1) > 1:
@@ -717,18 +977,22 @@
 
 def ApplyOverrides(error_tags, overrides):
   """Filters out all the error tags that overrides apply to.
-  
+
   O(N * M), but N and M are always small.
   """
   tags_after_overrides = []
+  applied_overrides = set([])
+  provided_overrides = set(copy.copy(overrides))
   for tag in error_tags:
     override_applies = False
     for override in overrides:
       if override.DoesApply(tag):
         override_applies = True
+        applied_overrides.add(override)
     if not override_applies:
       tags_after_overrides.append(tag)
-  return tags_after_overrides
+  unapplied_overrides = provided_overrides.difference(applied_overrides)
+  return tags_after_overrides, unapplied_overrides
 
 
 def GetIsalist():
@@ -744,16 +1008,16 @@
 
 class PackageStats(object):
   """Collects stats about a package and saves it."""
-  STATS_VERSION = 1L
   # This list needs to be synchronized with the CollectStats() method.
   STAT_FILES = [
       "all_filenames",
       "basic_stats",
       "binaries",
       "binaries_dump_info",
+      # "defined_symbols",
       "depends",
       "isalist",
-      "ldd_dash_r",
+      # "ldd_dash_r",
       "overrides",
       "pkginfo",
       "pkgmap",
@@ -849,10 +1113,11 @@
   def GetBasicStats(self):
     dir_pkg = self.GetDirFormatPkg()
     basic_stats = {}
-    basic_stats["stats_version"] = self.STATS_VERSION
+    basic_stats["stats_version"] = PACKAGE_STATS_VERSION
     basic_stats["pkg_path"] = self.srv4_pkg.pkg_path
     basic_stats["pkg_basename"] = os.path.basename(self.srv4_pkg.pkg_path)
-    basic_stats["parsed_basename"] = opencsw.ParsePackageFileName(basic_stats["pkg_basename"])
+    basic_stats["parsed_basename"] = opencsw.ParsePackageFileName(
+        basic_stats["pkg_basename"])
     basic_stats["pkgname"] = dir_pkg.pkgname
     basic_stats["catalogname"] = dir_pkg.GetCatalogname()
     return basic_stats
@@ -888,12 +1153,70 @@
       retcode = ldd_proc.wait()
       if retcode:
         logging.error("%s returned an error: %s", args, stderr)
-      lines = stdout.splitlines()
-      ldd_output[binary] = lines
+      ldd_info = []
+      for line in stdout.splitlines():
+        ldd_info.append(self._ParseLddDashRline(line))
+      ldd_output[binary] = ldd_info
     return ldd_output
 
+  def GetDefinedSymbols(self):
+    """Returns text symbols (i.e. defined functions) for packaged ELF objects
 
-  def CollectStats(self):
+    To do this we parse output lines from nm similar to the following. "T"s are
+    the definitions which we are after.
+
+      0000104000 D _lib_version
+      0000986980 D _libiconv_version
+      0000000000 U abort
+      0000097616 T aliases_lookup
+    """
+    dir_pkg = self.GetDirFormatPkg()
+    binaries = dir_pkg.ListBinaries()
+    defined_symbols = {}
+
+    for binary in binaries:
+      binary_abspath = os.path.join(dir_pkg.directory, "root", binary)
+      # Get parsable, ld.so.1 relevant SHT_DYNSYM symbol information
+      args = ["/usr/ccs/bin/nm", "-p", "-D", binary_abspath]
+      nm_proc = subprocess.Popen(
+          args,
+          stdout=subprocess.PIPE,
+          stderr=subprocess.PIPE)
+      stdout, stderr = nm_proc.communicate()
+      retcode = nm_proc.wait()
+      if retcode:
+        logging.error("%s returned an error: %s", args, stderr)
+        continue
+      nm_out = stdout.splitlines()
+
+      defined_symbols[binary] = []
+      for line in nm_out:
+        sym = self._ParseNmSymLine(line)
+        if not sym:
+          continue
+        if sym['type'] not in ("T", "D", "B"):
+          continue
+        defined_symbols[binary].append(sym['name'])
+
+    return defined_symbols
+
+  def _ParseNmSymLine(self, line):
+    re_defined_symbol =  re.compile('[0-9]+ [ABDFNSTU] \S+')
+    m = re_defined_symbol.match(line)
+    if not m:
+      return None
+    fields = line.split()
+    sym = { 'address': fields[0], 'type': fields[1], 'name': fields[2] }
+    return sym
+
+  def CollectStats(self, force=False):
+    if not self.StatsDirExists() or force:
+      self._CollectStats()
+
+  def _CollectStats(self):
+    """The list of variables needs to be synchronized with the one
+    at the top of this class.
+    """
     stats_path = self.GetStatsPath()
     self.MakeStatsDir()
     dir_pkg = self.GetDirFormatPkg()
@@ -907,7 +1230,10 @@
     self.DumpObject(self.GetOverrides(), "overrides")
     self.DumpObject(dir_pkg.GetParsedPkginfo(), "pkginfo")
     self.DumpObject(dir_pkg.GetPkgmap().entries, "pkgmap")
-    self.DumpObject(self.GetLddMinusRlines(), "ldd_dash_r")
+    # This check is currently disabled, let's save time by not collecting
+    # these data.
+    # self.DumpObject(self.GetLddMinusRlines(), "ldd_dash_r")
+    # self.DumpObject(self.GetDefinedSymbols(), "defined_symbols")
     logging.debug("Statistics collected.")
 
   def GetAllStats(self):
@@ -942,17 +1268,18 @@
     in_file_name = os.path.join(stats_path, "%s.yml" % name)
     in_file_name_pickle = os.path.join(stats_path, "%s.pickle" % name)
     if os.path.exists(in_file_name_pickle):
-      logging.debug("ReadObject(): reading %s", repr(in_file_name_pickle))
+      # logging.debug("ReadObject(): reading %s", repr(in_file_name_pickle))
       f = open(in_file_name_pickle, "r")
       obj = cPickle.load(f)
       f.close()
-      logging.debug("ReadObject(): finished reading %s", repr(in_file_name_pickle))
+      # logging.debug("ReadObject(): finished reading %s",
+      #               repr(in_file_name_pickle))
     else:
-      logging.debug("ReadObject(): reading %s", repr(in_file_name))
+      # logging.debug("ReadObject(): reading %s", repr(in_file_name))
       f = open(in_file_name, "r")
       obj = yaml.safe_load(f)
       f.close()
-      logging.debug("ReadObject(): finished reading %s", repr(in_file_name))
+      # logging.debug("ReadObject(): finished reading %s", repr(in_file_name))
     return obj
 
   def ReadSavedStats(self):
@@ -960,3 +1287,40 @@
     for name in self.STAT_FILES:
       all_stats[name] = self.ReadObject(name)
     return all_stats
+
+  def _ParseLddDashRline(self, line):
+    found_re = r"^\t(?P<soname>\S+)\s+=>\s+(?P<path_found>\S+)"
+    symbol_not_found_re = r"^\tsymbol not found:\s(?P<symbol>\S+)\s+\((?P<path_not_found>\S+)\)"
+    only_so = r"^\t(?P<path_only>\S+)$"
+    version_so = r'^\t(?P<soname_version_not_found>\S+) \((?P<lib_name>\S+)\) =>\t \(version not found\)'
+    common_re = r"(%s|%s|%s|%s)" % (found_re, symbol_not_found_re, only_so, version_so)
+    m = re.match(common_re, line)
+    response = {}
+    if m:
+      d = m.groupdict()
+      if "soname" in d and d["soname"]:
+        # it was found
+        response["state"] = "OK"
+        response["soname"] = d["soname"]
+        response["path"] = d["path_found"]
+        response["symbol"] = None
+      elif "symbol" in d and d["symbol"]:
+        response["state"] = "symbol-not-found"
+        response["soname"] = None
+        response["path"] = d["path_not_found"]
+        response["symbol"] = d["symbol"]

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.


More information about the devel mailing list