summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Stone <ahs3@redhat.com>2012-11-26 12:23:17 -0700
committerAl Stone <ahs3@redhat.com>2012-11-26 12:23:17 -0700
commit69c6f928b5589e3f50fad870da1e8b345d466a98 (patch)
treee3cd40819325b05cbe861dbb035fc390498dd1e3
downloadportdep-69c6f928b5589e3f50fad870da1e8b345d466a98.tar.gz
portdep-69c6f928b5589e3f50fad870da1e8b345d466a98.tar.xz
portdep-69c6f928b5589e3f50fad870da1e8b345d466a98.zip
initial commit
Signed-off-by: Al Stone <ahs3@redhat.com>
-rw-r--r--packages/fedora81
-rwxr-xr-xportdep.sh181
-rwxr-xr-xscanners/dot-s-files.sh15
-rwxr-xr-xscanners/ifdefs.py56
-rwxr-xr-xscanners/which-asm.sh43
5 files changed, 376 insertions, 0 deletions
diff --git a/packages/fedora b/packages/fedora
new file mode 100644
index 0000000..cf50a2a
--- /dev/null
+++ b/packages/fedora
@@ -0,0 +1,81 @@
+#!/bin/bash
+#-- make sure we know how to handle the distro
+# Each file needs to define a function called get_source that will
+# be passed the working directory and a package name, and that must
+# return the full absolute path to the source tree.
+#
+# A similar remove_source function must also be defined (same parameters)
+# that just removes everything created in the working directory for this
+# package.
+#
+
+get_source() {
+ pwd=$(pwd)
+ workdir="$1"
+ pkg="$2"
+
+ #-- set up the proper environment
+ cd "$workdir"
+ [ ! -d $pkg ] && mkdir $pkg
+ cd $pkg
+ [ ! -d rpmbuild ] && mkdir rpmbuild
+ for ii in BUILD SOURCES SPECS SRPMS
+ do
+ [ ! -d rpmbuild/$ii ] && mkdir rpmbuild/$ii
+ done
+ rpmhome="$workdir/$pkg"
+
+ #-- fetch the bits from fedpkg
+ if [ -d $pkg ]
+ then
+ res=$(cd $pkg; fedpkg pull >/dev/null 2>&1)
+ else
+ res=$(fedpkg clone -a $pkg >/dev/null 2>&1)
+ fi
+ if [ ! -d $pkg ]
+ then
+ echo ""
+ cd $pwd
+ exit 1
+ fi
+
+ #-- get the srpm made
+ cd $pkg
+ res=$(fedpkg srpm >/dev/null 2>&1)
+ fname=$(ls -1 *.src.rpm | head -1)
+ if [ -z "$fname" ]
+ then
+ echo ""
+ cd $pwd
+ exit 1
+ fi
+
+ #-- unpack the srpm
+ srpm=$(ls -1 | grep .src.rpm | head -1)
+ res=$(HOME=$rpmhome rpm -i $srpm >/dev/null 2>&1)
+
+ #-- unpack the source and apply the patches
+ cd $rpmhome/rpmbuild/SPECS
+ res=$(HOME=$rpmhome rpmbuild --nodeps -bp ${pkg}.spec >/dev/null 2>&1)
+
+ #-- all done. as you were. and report the path.
+ path=$(ls $rpmhome/rpmbuild/BUILD | grep $pkg | head -1)
+ if [ ! -z $path ]
+ then
+ echo $rpmhome/rpmbuild/BUILD/$path
+ else
+ echo ""
+ fi
+ cd $pwd
+}
+
+remove_source () {
+ pwd=$(pwd)
+ workdir="$1"
+ pkg="$2"
+
+ cd "$workdir"
+ rm -rf $pkg >/dev/null 2>&1
+
+ cd $pwd
+}
diff --git a/portdep.sh b/portdep.sh
new file mode 100755
index 0000000..cef8c6c
--- /dev/null
+++ b/portdep.sh
@@ -0,0 +1,181 @@
+#!/bin/bash
+#
+# For each package in a list, run a set of one or more scanners
+# over the source files looking for potential machine dependent
+# code (i.e., portability dependencies).
+#
+
+#-- functions
+usage () {
+ name=$(basename $0)
+ echo "$name: scan source files for portability issues"
+ echo
+ echo "$name --pkglist <filename> --distro <distroname>"
+ echo " [--keep] [--output <filename>] [--workdir <dirname>]"
+ echo
+ echo "where:"
+ echo " --keep => if given, do not remove any of"
+ echo " the downloaded sources (WARNING!"
+ echo " this is a LOT of GiBs)"
+ echo " --pkglist <filename> => list of packages to scan,"
+ echo " one package name per line"
+ echo " --distro <filename> => one of: fedora, debian"
+ echo " --output <filename> => where to report results"
+ echo " (default: scan.results)"
+ echo " --workdir <dirname> => temporary working directory"
+ echo " for source trees and other"
+ echo " stuff (default: ./work)"
+}
+
+run_scanners () {
+ #-- run all scanners listed in ./scanners
+ # Each file is an independent executable, and will be passed
+ # be passed the working directory, package name, and the full
+ # path to the source tree. In turn, whatever is executed needs
+ # to return a single output line that has this form:
+ #
+ # <scanner-name>: <value>
+ #
+ # For example:
+ # Dot-S-Files: 3
+ #
+ # The name may not have white space in it, and a value of 0
+ # means the scan worked but found nothing, a value > 0 means
+ # something possibly problematic was found (larger implies more
+ # problematic), and a value of -1 means an error occurred.
+ #
+ workdir="$1"
+ pkg=$2
+ src=$3
+ echo >> $output
+ echo "Package: $pkg" >> $output
+ echo "Source: $(basename $src)" >> $output
+ for ii in $(ls scanners)
+ do
+ result=$(scanners/$ii $workdir $src 2>&1)
+ echo "$result" >> $output
+ done
+}
+
+#-- input argument handling
+distro=""
+keep="no"
+output="scan.results"
+pkglist=""
+workdir="$(pwd)/work"
+
+while [ $# -gt 0 ]
+do
+ arg="$1"
+ shift
+ case $arg in
+ --distro) # which unpacking scheme is needed for source
+ if [ $# -gt 0 ]
+ then
+ dname=$1
+ shift
+ case $dname in
+ fedora|debian)
+ distro=$dname
+ ;;
+ *)
+ echo "? no such distro: $dname"
+ exit 1
+ esac
+ else
+ echo "? must supply distro name"
+ exit 1
+ fi
+ ;;
+ --keep)
+ keep="yes"
+ ;;
+ --output) # where to store the scan results
+ if [ $# -gt 0 ]
+ then
+ output=$1
+ else
+ echo "? must supply output file name"
+ exit 1
+ fi
+ ;;
+ --pkglist) # which packages to scan
+ if [ $# -gt 0 ]
+ then
+ plist=$1
+ shift
+ if [ -f $plist ]
+ then
+ pkglist=$plist
+ else
+ echo "? no such file: $plist"
+ exit 1
+ fi
+ else
+ echo "? must supply package list file name"
+ exit 1
+ fi
+ ;;
+ --workdir) # temporary working dir for source trees
+ if [ $# -gt 0 ]
+ then
+ workdir=$1
+ else
+ echo "? must supply work directory name"
+ exit 1
+ fi
+ ;;
+ *)
+ echo "? unknown parameter: $arg"
+ usage
+ exit 1
+ esac
+done
+
+if [ -z $distro ]
+then
+ echo "? --distro is a required parameter"
+ exit 1
+fi
+
+if [ -z $pkglist ]
+then
+ echo "? --pkglist is a required parameter"
+ exit 1
+fi
+
+#-- make sure we know how to handle the distro
+# Each file needs to define a function called get_source that will
+# be passed the working directory and a package name, and that must
+# return the full absolute path to the source tree.
+#
+# There must also be a similar remove_source (same parameters) that
+# cleans up and removes all sources for a package.
+if [ ! -f packages/$distro ]
+then
+ echo "? internal error: no script for distro $distro"
+ exit 2
+fi
+source packages/$distro
+
+#-- for each package in the list, scan it and report results
+[ ! -d "$workdir" ] && mkdir -p "$workdir"
+rm -f $output
+cat $pkglist | (
+ read line
+ while [ "$line" ]
+ do
+ echo "scanning => $line"
+ res=$(get_source "$workdir" $line)
+ if [ ! -z "$res" ]
+ then
+ run_scanners "$workdir" $line $res
+ fi
+ if [ $keep == "no" ]
+ then
+ remove_source "$workdir" $line
+ fi
+ read line
+ done
+)
+
diff --git a/scanners/dot-s-files.sh b/scanners/dot-s-files.sh
new file mode 100755
index 0000000..0fb7f18
--- /dev/null
+++ b/scanners/dot-s-files.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+scanner="Dot-S-Files"
+
+workdir="$1"
+src="$2"
+
+if [ -d "$src" ]
+then
+ count=$(find "$src" -name '*\.[sS]' -print | wc -l)
+else
+ count="-1"
+fi
+echo "${scanner}: $count"
+
diff --git a/scanners/ifdefs.py b/scanners/ifdefs.py
new file mode 100755
index 0000000..ba817fa
--- /dev/null
+++ b/scanners/ifdefs.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+
+import os
+import os.path
+import re
+import subprocess
+import sys
+
+def main():
+ '''this scanner counts up the number of instances of #ifdef that
+ have an architecture name in them.
+ '''
+ path = sys.argv[2]
+
+ arches = ['__alpha__', '__alpha_ev[0-9]+__',
+ '__amd64__', '__x64_64__',
+ '__arm__', '__thumb__', '__TARGET_ARM_[0-9A-Z]+__',
+ '__convex__', '__convex_[0-9]+__',
+ '__epiphany__',
+ '__hppa__', '__PA_RISC[0-9]_[0-9]__', '__HPPA[0-9]+__',
+ '__PA[0-9][0-9]00__',
+ '__i[3-6]86__',
+ '__ia64__',
+ '__m68k__', '__mc680[0-9]0__', '__MC680[0-9]0__',
+ '__mips__', '__MIPS_ISA_MIPS[0-9]__',
+ '__powerpc__', '__ppc[0-9]*__',
+ '__sparc__',
+ '__sh[0-9]__',
+ '__s390__', '__s390x__',
+ '__TMS320[0-9A-Z]*__',
+ '__TMS470__',
+ ]
+
+ cmd = 'grep -hr \'^#if[ \\t]*def.*\' %s' % path
+ count = 0
+ findings = ""
+ try:
+ prog = re.compile('|'.join(arches))
+ findings = subprocess.check_output(cmd, shell=True)
+ if findings:
+ for ii in findings.split('\n'):
+ if prog.search(ii):
+ count += 1
+ except subprocess.CalledProcessError, e:
+ if e.returncode == 1: # usually means nothing found
+ count = 0
+ else:
+ count = -1
+
+ result = 'Ifdef-Arch: %d' % count
+ return result
+
+if __name__ == '__main__':
+ result = main()
+
+print result
diff --git a/scanners/which-asm.sh b/scanners/which-asm.sh
new file mode 100755
index 0000000..6e63ed2
--- /dev/null
+++ b/scanners/which-asm.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+scanner="Which-Asm"
+
+workdir="$1"
+src="$2"
+
+WHICHASM=whichasm
+
+count=0
+if [ -d "$src" ]
+then
+ find "$src" \( -name '*\.[cCsShH]' \
+ -o -name '*\.cc' \
+ -o -name '*\.cxx' \
+ -o -name '*\.cpp' \
+ \) -print > /tmp/$$
+ if [ -s /tmp/$$ ]
+ then
+ count=$(cat /tmp/$$ | (
+ count=0
+ read line
+ while [ ! -z $line ]
+ do
+ res=$(${WHICHASM} $line)
+ if [ "$(echo $res | grep ^error:)" ] || \
+ [ "$(echo $res | grep '.*: unknown')" ]
+ then
+ true
+ else
+ count+=1
+ fi
+ read line
+ done
+ echo $count
+ ))
+ fi
+ rm -f /tmp/$$
+else
+ count="-1"
+fi
+echo "${scanner}: $count"
+