Initial commit of vpp code.
[vpp.git] / build-root / autowank
diff --git a/build-root/autowank b/build-root/autowank
new file mode 100755 (executable)
index 0000000..0589706
--- /dev/null
@@ -0,0 +1,308 @@
+#!/bin/bash
+
+# Copyright (c) 2015 Cisco and/or its affiliates.
+# 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.
+
+# This aptly-named script verifies and fixes time ordering
+# problems with Makefile.{am,in} aclocal.m4 configure* files.
+
+set -eu
+#set -vx
+
+touch=""
+commit=""
+comma_v=""
+aclocal=""
+optimize=""
+
+# The old autowank scheme used "touch <foo> ; sleep 1"
+# to ensure differentiable, ordered timestamps. Worked, but
+# took N seconds given N files to fix. We have an example
+# which wastes multiple minutes given the old scheme.
+#
+# This version generates a sequence of timestamps 
+# starting an hour ago. That gives us
+# lots to play with, in case some obnoxious program feels the need
+# to complain about timestamps in the future.
+
+# If we're in UTC+N land, generate UTC+(N+1) 
+# If we're in UTC-N land, generate UTC-(N-1)
+
+my_tz=`date +%z`
+sign=`echo $my_tz | sed -n -e 's/^\(.\{1\}\).*$/\1/p'`
+t=`echo $my_tz | sed -n -e 's/^\(.\{1\}\)//p'`
+tz_hour=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
+tz_hour=`echo $tz_hour | sed 's/^0//'`
+
+if [ $sign = "-" ] ; then
+    sign="+"
+    let tz_hour=$tz_hour+1
+    if [[ $tz_hour -ge "24" ]] ; then
+        tz_hour=0
+    fi
+else
+    sign="-"
+    let tz_hour=$tz_hour-1 || true
+    if [[ $tz_hour -lt "0" ]] ; then
+        tz_hour=23
+    fi
+fi
+
+# Timestamp, an hour ago:
+ts_begin=`TZ=UTC${sign}${tz_hour} date +%Y%m%d%H%M.%S`
+
+# break into constituent parts
+year=`echo $ts_begin | sed -n -e 's/^\(.\{4\}\).*$/\1/p'`
+t=`echo $ts_begin | sed -n -e 's/^\(.\{4\}\)//p'`
+month=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
+t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
+day=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
+t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
+hour=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
+t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
+min=`echo $t | sed -n -e 's/^\(.\{2\}\).*$/\1/p'`
+t=`echo $t | sed -n -e 's/^\(.\{2\}\)//p'`
+sec=`echo $t | sed -n -e 's/\.//p'`
+
+# How many days in the current month?
+# Good until someone changes the calendar rules
+days_in_current_month() {
+    if [[ $month -eq 9 || $month -eq 4 \
+        || $month -eq 6 || $month -eq 11 ]] ; then
+       return 30;
+    fi
+    if [[ $month -eq 2 ]] ; then
+       let t=($year/400)*400
+       if [[ $t -eq $year ]] ; then
+           return 29;
+       fi
+       let t=($year/100)*100
+       if [[ $t -eq $year ]] ; then
+           return 28;
+       fi
+       let t=($year/4)*4
+       if [[ $t -eq $year ]] ; then
+           return 29;
+       fi
+       return 28;
+    fi
+    return 31;
+}
+
+# The next timestamp to issue via touch
+# A real hemorrhoid because bash isnt easily convinced
+# that 08 is a decimal number
+next_ts() {
+    sec=`echo $sec | sed 's/^0//'`
+    let sec=$sec+1
+    if [[ "$sec" -lt "60" ]] ; then
+        if [[ "$sec" -lt "10" ]] ; then
+            sec=0$sec
+        fi
+       return 0;
+    fi
+    sec="00"
+    min=`echo $min | sed 's/^0//'`
+    let min=$min+1
+    if [[ "$min" -lt "60" ]] ; then
+        if [[ "$min" -lt "10" ]] ; then
+            min=0$min
+        fi
+       return 0;
+    fi
+    min="00"
+    hour=`echo $hour | sed 's/^0//'`
+    let hour=$hour+1
+    if [[ "$hour" -lt "24" ]] ; then
+        if [[ "$hour" -lt "10" ]] ; then
+            hour=0$hour
+        fi
+       return 0;
+    fi
+    hour="00"
+    days_in_current_month
+    days_in_month=$?
+    if [[ "$day" -lt "$days_in_month" ]] ; then
+        day=`echo $day | sed 's/^0//'`
+       let day=$day+1
+        if [[ "$day" -lt "10" ]] ; then
+            day=0$day
+        fi
+       return 0;
+    fi
+    day="01"
+    month=`echo $month | sed 's/^0//'`
+    let month=$month+1
+    if [[ "$month" -lt "13" ]] ; then
+        if [[ "$month" -lt "10" ]] ; then
+            month=0$month
+        fi
+       return 0;
+    fi
+    month="01"
+    let year=$year+1
+    return 0;
+}
+
+while [ $# != 0 ] ; do
+  case "$1" in
+    (--commav) comma_v=",v" ;;
+    (--touch) touch=yes ;;
+    (--aclocal) aclocal=yes ;;
+    (--nooptimize) optimize="" ;;
+    (--commit=*) commit="$1" ;;
+    (*) echo "$0: usage [--touch|--commit|]" > /dev/stderr
+        exit 17 ;;
+  esac
+  shift
+done
+
+if [ "${aclocal}" != "" ] ; then
+    if [ -f aclocal.m4 ] ; then
+        echo touching aclocal.m4
+        sleep 1
+        touch aclocal.m4
+    else
+        echo aclocal.m4 not found
+    fi
+fi
+
+if [ "${comma_v}" != "" -a "${commit}" != "" ] ; then
+  echo "No, you may NOT molest ,v files directly.  Go away." > /dev/stderr
+  exit 1
+fi
+
+function touchme ()
+{
+  local victim="${1}"
+  shift
+  local touchmebaby=""
+  local sein="is"
+  local newer="no"
+  local older="no"
+
+  if [ ! -r "$victim" ] ; then
+    echo "  Possible problem: No $victim exists. " > /dev/stderr 
+    return
+  fi
+
+  while [ $# != 0 ] ; do
+    if [ "${1}" -nt "${victim}" ] ; then
+        newer="yes"
+    fi
+    if [ "${1}" -ot "${victim}" ] ; then
+        older="yes"
+    fi
+    if [ "${newer}" = "no" -a "${older}" = "no" ] ; then
+        newer="yes"
+    fi
+
+    if [ "${newer}" = "yes" ] ; then
+      if [ "${touchmebaby}" = "" ] ; then
+        touchmebaby="${1}"
+      else
+        sein="are"
+        touchmebaby="${touchmebaby} ${1}"
+      fi
+    fi
+    shift
+  done
+  if [ -n "${touchmebaby}" ] ; then
+    echo "*** ${touchmebaby} ${sein} newer than ${victim}  "
+    if [ -n "${touch}" ] ; then
+      # 
+      # This is the old version, in case something backfires...
+      if [ "${optimize}" != "yes" ] ; then 
+          echo "Fixing " ;touch -c "$victim" ; sleep 1
+      else
+          echo "Fixing "
+      # echo touch -c -t $year$month$day$hour$min.$sec "$victim"
+          touch -c -t $year$month$day$hour$min.$sec "$victim"
+          next_ts
+      fi
+    fi
+  fi
+}
+
+makefileins="`/usr/bin/find . -name Attic -prune -o -name Makefile.in${comma_v}`"
+
+# aclocal.m4 depends on ***/Makefile.am, configure.ac, acinclude.m4, *.m4 crap
+touchme aclocal.m4${comma_v} \
+        `/usr/bin/find . -name Attic -prune -o -name Makefile.am${comma_v}` \
+        "configure.in${comma_v}" "configure.ac${comma_v}" \
+        "acinclude.m4${comma_v}"
+
+# Makefile.in must be newer than Makefile.am
+for f in $makefileins ; do
+  d="`dirname ${f}`"
+  touchme "${d}/Makefile.in${comma_v}" "${d}/Makefile.am${comma_v}"
+done
+
+# Makefile.in depends on aclocal.m4
+for f in $makefileins ; do
+  d="`dirname $f`"
+  touchme "${d}/Makefile.in${comma_v}" "aclocal.m4${comma_v}"
+done
+
+# config.in must be newer than aclocal.m4 and configure.ac
+if [ -f "config.in${comma_v}" ] ; then
+  touchme "config.in${comma_v}" "aclocal.m4${comma_v}" \
+                                "configure.ac${comma_v}" \
+                                "configure.in${comma_v}"
+fi
+
+# config.h.in (or More Thoroughly Modern configh.in)
+# must be newer than aclocal.m4 and (obsolete) acconfig.h
+for c_h_in in config.h.in configh.in ; do
+  if [ -f "${c_h_in}${comma_v}" ]; then
+    touchme "${c_h_in}${comma_v}" "aclocal.m4${comma_v}" "acconfig.h${comma_v}"
+    #>>>> WTF?  Why?  This is nonsensical
+    ## ***/Makefile.in must be newer than config.h.in
+    #for f in $makefileins ; do
+    #  touchme "$f" "${c_h_in}${comma_v}"
+    #done
+  fi
+done
+
+# configure must be newer than everything
+# touchme configure $makefileins -- why would this be needed?
+touchme "configure${comma_v}" "aclocal.m4${comma_v}" "acconfig.h${comma_v}" \
+                              "config.in${comma_v}" "config.h.in${comma_v}" \
+                              "configh.in${comma_v}"
+
+if [ -n "${commit}" ] ; then
+  commit="${commit:9}" # strip off "--commit="
+  # First ***/Makefile.am,
+  # configure.in, configure.ac,
+  # ***/*.m4
+  # acconfig.h
+  cvs commit -m "${commit}" \
+             `for f in ${makefileins} ; do \
+                [ -f "$${f%.in}.am" ] && echo "$${f%.in}.am" ; \
+              done` \
+             `[ -f configure.in ] && echo configure.in` \
+             `[ -f configure.ac ] && echo configure.ac` \
+             `[ -f acconfig.h ] && echo acconfig.h` \
+             `/usr/bin/find . -name '*.m4' -mindepth 2`
+
+  # Next aclocal.m4
+  [ -f "aclocal.m4" ] && cvs commit -m "${commit}" aclocal.m4
+
+  # Next config.in, config.h.in, configh.in
+  [ -f "config.in" ] && cvs commit -m "${commit}" config.in
+  [ -f "config.h.in" ] && cvs commit -m "${commit}" config.h.in
+  [ -f "configh.in" ] && cvs commit -m "${commit}" configh.in
+
+  # Last ***/Makefile.in, configure
+  cvs commit -m "${commit}" ${makefileins} configure
+fi