#!/bin/sh 

##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
## 
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
## 
##    http://www.apache.org/licenses/LICENSE-2.0
## 
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************


# Analyzes and compares condor_syscall_lib.a to libc.a
# Todd Tannenbaum, 7/97
# Made portable and added super perl-tastic man page parsing, 
# Derek Wright, 6/98

######################################################################
# Configurable settings
######################################################################
SYSCALL_LIB='../condor_syscall_lib/libcondorsyscall.a'

######################################################################
# Figure out the platform-specific junk:
######################################################################

UNAME=`uname`

if [ -f /lib/libc.a ]; then
	LIBC=/lib/libc.a
elif [ -f /usr/lib/libc.a ]; then
	LIBC=/usr/lib/libc.a
elif [ -f /lib/libc.so.1 ]; then
	LIBC=/lib/libc.so.1
else 
	echo "Can't find libc.a"
	exit 1
fi

if [ -f /usr/include/syscall-list.h ]; then
	SYSCALL=/usr/include/syscall-list.h
elif [ -f /usr/include/bits/syscall.h ]; then
	SYSCALL=/usr/include/bits/syscall.h
elif [ -f /usr/include/sys.s ]; then
	SYSCALL=/usr/include/sys.s
elif [ -f /usr/include/sys/syscall.h ]; then
	SYSCALL=/usr/include/sys/syscall.h
else
	echo "Can't find syscall.h"
	exit 1
fi

NM="nm -P"

######################################################################
## Real work begins
######################################################################


# place all the system calls on this platform sorted into /tmp/asc1.$$
grep "#define" $SYSCALL | grep "SYS_" | awk '{print $2}' | sed 's/SYS_//' \
	| tr "[:upper:]" "[:lower:]" | sort | uniq > /tmp/asc1.$$

# place all global functions in SYSCALL_LIB into /tmp/asc2.$$
# for C++ objects, just report the object with "[C++]" appended instead
# of all the C++ methods.
$NM $SYSCALL_LIB | grep " T " | c++filt | \
   sed 's/::[^ ]*/\[C++\]/' | awk '{print $1}' - | sort | uniq  > /tmp/asc2.$$

# store trapped calls into /tmp/asc3.$$ and pretty print them 
echo "*** SYSTEM CALLS TRAPPED BY CONDOR"
comm -12 /tmp/asc1.$$ /tmp/asc2.$$ | tee /tmp/asc3.$$ | awk \
'{ printf "%20.20s",sprintf("%s()",$0)
   i++
   items++
   if (i > 2) {
	  i = 0
	  printf "\n"
   }
}
END { if ( i != 0 )
		printf "\n"
	  printf "--- %d items.\n\n",items  }
' -

# pretty print all trapped system calls which are supported by condor.
# do this by refering to the output from stub-gen -mode listcalls
# for all calls in switches.o, and the assume (sigh) that any others
# in misc files included in syscall_lib.a are supported.

# first take everything in switches.o out of asc2.$$, cuz we wanna
# use the output from stub-gen as more authoratative on if it is
# supported or not.  save into asc4.$$
$NM ../condor_syscall_lib/switches.o | grep " T " | awk '{print $1}' - | \
   sort | uniq | comm -23 /tmp/asc2.$$ - > /tmp/asc4.$$
# Now list the supported calls
echo "*** SYSTEM CALLS TRAPPED AND _SUPPORTED_ BY CONDOR"
grep "|S|" ../condor_syscall_lib/syscall-list | awk -F\| '{print $1}' - | \
   sort | uniq | comm -12 /tmp/asc2.$$ - |
   cat - /tmp/asc3.$$ /tmp/asc4.$$ | sort | uniq -d | awk \
'{ printf "%20.20s",sprintf("%s()",$0)
   i++
   items++
   if (i > 2) {
	  i = 0
	  printf "\n"
   }
}
END { if ( i != 0 )
		printf "\n"
	  printf "--- %d items.\n\n",items  }
' -

# pretty print all trapped system calls which are unsupported by condor.
# simply use what stub-gen tells us.
echo "*** SYSTEM CALLS TRAPPED AND _UNSUPPORTED_ BY CONDOR"
grep "|U|" ../condor_syscall_lib/syscall-list | awk -F\| '{print $1}' - | \
   sort | uniq | comm -12 /tmp/asc2.$$ - |
   awk \
'{ printf "%20.20s",sprintf("%s()",$0)
   i++
   items++
   if (i > 2) {
	  i = 0
	  printf "\n"
   }
}
END { if ( i != 0 )
		printf "\n"
	  printf "--- %d items.\n\n",items  }
' -

# pretty print all trapped system calls which are ignored by condor.
# simply use what stub-gen tells us.
echo "*** SYSTEM CALLS TRAPPED AND _IGNORED_ BY CONDOR"
grep "|I|" ../condor_syscall_lib/syscall-list | awk -F\| '{print $1}' - | \
   sort | uniq | comm -12 /tmp/asc2.$$ - |
   awk \
'{ printf "%20.20s",sprintf("%s()",$0)
   i++
   items++
   if (i > 2) {
	  i = 0
	  printf "\n"
   }
}
END { if ( i != 0 )
		printf "\n"
	  printf "--- %d items.\n\n",items  }
' -

echo "*** SYSTEM CALLS NOT TRAPPED AT ALL BY CONDOR"
NOTTRAPPED=`comm -23 /tmp/asc1.$$ /tmp/asc3.$$`

for SYSCALL in $NOTTRAPPED 
do
	echo $SYSCALL | awk '{printf "%20.20s - ",sprintf("%s()",$0)}' - 
	perl ./display_syscall_man $SYSCALL
done
echo " "

echo "*** WARNING: ALL SYSTEM CALLS IN SYSCALL.TMPL BUT NOT IN SYSCALLS.H,"
echo "*** AND NOT TRAPPED SOMEPLACE OTHER THAN SWITCHES.O"
awk -F\| '{print $1}' ../condor_syscall_lib/syscall-list | \
   sort | uniq | comm -13 /tmp/asc1.$$ - | comm -13 /tmp/asc4.$$ - |
   awk \
'{ printf "%20.20s",sprintf("%s()",$0)
   i++
   items++
   if (i > 2) {
	  i = 0
	  printf "\n"
   }
}
END { if ( i != 0 )
		printf "\n"
	  printf "--- %d items.\n\n",items  }
' -

echo "*** ALL UNDERSCORE SYSTEM CALLS FOUND IN LIBC"
$NM $LIBC | awk '{print $1}' -  | sort | uniq > /tmp/asc5.$$
awk '{printf "_%s\n__%s\n__libc_%s\n___%s\n____%s\n",$0,$0,$0,$0,$0}' /tmp/asc1.$$  |\
   cat - /tmp/asc5.$$ | sort | uniq -d  | tee /tmp/asc6.$$ | awk \
'{ printf "%20.20s",sprintf("%s()",$0)
   i++
   items++
   if (i > 2) {
	  i = 0
	  printf "\n"
   }
}
END { if ( i != 0 )
		printf "\n"
	  printf "--- %d items.\n\n",items  }
' -

echo "*** UNDERSCORE SYSTEM CALLS TRAPPED IN CONDOR"
awk '{printf "_%s\n__%s\n__libc_%s\n___%s\n____%s\n",$0,$0,$0,$0,$0}' /tmp/asc3.$$  |\
   sort | tee /tmp/asc8.$$ | cat - /tmp/asc2.$$ | sort | uniq -d  |\
   tee /tmp/asc7.$$ | awk \
'{ printf "%20.20s",sprintf("%s()",$0)
   i++
   items++
   if (i > 2) {
	  i = 0
	  printf "\n"
   }
}
END { if ( i != 0 )
		printf "\n"
	  printf "--- %d items.\n\n",items  }
' -

# Store the missed underscore calls in asc9.$$
echo "*** -->MISSED UNDERSCORE CALLS FOR TRAPPED CALLS IN CONDOR<--"
comm -23 /tmp/asc6.$$ /tmp/asc7.$$ | comm -12 - /tmp/asc8.$$ |\
	tee /tmp/asc9.$$ | awk \
'{ printf "%20.20s",sprintf("%s()",$0)
   i++
   items++
   if (i > 2) {
	  i = 0
	  printf "\n"
   }
}
END { if ( i != 0 )
		printf "\n"
	  printf "--- %d items.\n\n",items  }
' -

echo "*** SUGGESTED MACRO CALLS TO INSERT INTO switches.prolog"
MISSED=`cat /tmp/asc9.$$`
for UNDERSCORE in $MISSED
do
	SYSCALL=`echo "$UNDERSCORE" | sed -e 's/^__libc_*//' -e 's/^_*//'`
	PROTO=A`grep "^$SYSCALL|" ../condor_syscall_lib/syscall-list`
	if [ "$PROTO" != "A" ]; then
		# found it in syscall-list, thus we have a prototype
		echo "$PROTO"\| "$SYSCALL"\| "$UNDERSCORE" |\
			awk -F\| '{printf "REMAP_%s(%s,%s, %s)\n",$4,$5,$6,$3}' -
	else
		# not found in syscall-list... user will need to do by hand
		echo "REMAP_UNKNOWN( $SYSCALL, $UNDERSCORE, ...args... )"
	fi
done
echo " "

echo "*** LIKELY FUNCTION/OBJECT NAMESPACE CLUTTER IN condor_syscall_lib"
cat /tmp/asc3.$$ /tmp/asc7.$$ | sort | comm -23 /tmp/asc2.$$ - |\
	grep -v -i '^_condor' | awk \
'{ 
   if ( $0 ~ /C\+\+/ ) {
      printf "%30.30s",sprintf("%s",$0)
   } else {
      printf "%30.30s",sprintf("%s()",$0)
   }
   i++
   items++
   if (i > 1) {
	  i = 0
	  printf "\n"
   }
}
END { if ( i != 0 )
		printf "\n"
	  printf "--- %d items.\n\n",items  }
' -
echo " "


echo "*** LIKELY VARIABLE NAMESPACE CLUTTER IN condor_syscall_lib"
$NM $SYSCALL_LIB | grep " D " | c++filt | \
   sed 's/::[^ ]*/\[C++\]/' | awk '{print $1}' - | sort | uniq |\
   grep -v -i '^_condor' | awk \
'{ printf "%20.20s",sprintf("%s",$0)
   i++
   items++
   if (i > 2) {
	  i = 0
	  printf "\n"
   }
}
END { if ( i != 0 )
		printf "\n"
	  printf "--- %d items.\n\n",items  }
' -
echo " "


# remove all our temp file!
rm -f /tmp/asc1.$$
rm -f /tmp/asc2.$$
rm -f /tmp/asc3.$$
rm -f /tmp/asc4.$$
rm -f /tmp/asc5.$$
rm -f /tmp/asc6.$$
rm -f /tmp/asc7.$$
rm -f /tmp/asc8.$$
rm -f /tmp/asc9.$$

