#!/bin/sh
# tla-abbrev-merge-log -- Abbreviate redundant tla log-for-merge output
#
#  Copyright (C) 2004  Miles Bader <miles@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Written by Miles Bader <miles@gnu.org>
#-
# This filter makes the output of `tla log-for-merge' more concise by
# replacing a series of revisions that have the same summary line with an
# abbreviated format that only shows the beginning and end revisions, and
# the common summary line.

# (---- beginning of hdr.shpp ----)
# hdr.shpp

me=`basename $0`

bindir='/usr/bin'
AWK='/usr/bin/nawk'; export AWK
TLA='tla'; export TLA
SED='/bin/sed'; export SED
UUIDGEN='uuidgen'; export UUIDGEN

# (---- TLA_TOOLS_VERSION defined from ,tla-tools-version ----)
TLA_TOOLS_VERSION='jgoerzen@complete.org--debian/tla-tools--debian--1.0--patch-18
'
# (---- end of TLA_TOOLS_VERSION defined from ,tla-tools-version ----)

TLA_TOOL_PFX="${bindir+$bindir/}"
export TLA_TOOL_PFX

TLA_ESCAPE='yes'

if test "$TLA_ESCAPE" = yes; then
  TLA_UNESCAPED_OPT='--unescaped'
else
  TLA_UNESCAPED_OPT=''
fi

# Some tools get completely confused in stupid ways by non-default
# settings of LANG (like gawk, which fucks up regexp character ranges).
LANG=C; export LANG

# (---- end of hdr.shpp ----)
# (---- beginning of simple-cmd-line.shpp ----)
# simple-cmd-line.shpp -- Simple command-line processing for no-option commands

# (---- beginning of cmd-line.shpp ----)
# cmd-line.shpp -- Command-line helper functions for shell scripts

script="$0"
case "$script" in
  */*) ;;
  *)   script="${TLA_TOOL_PFX}$script";;
esac

usage ()
{
  $SED -n -e '/^\([^#]\|#-* *$\)/{s@.*@Usage: '"$me"' [--help|--version]@p;q;}'	\
         -e '/^# *Usage:/,/^# *$/{s/^# //p;q;}'				\
     < "$script"
}

short_help ()
{
  $SED -n -e '/^\([^#]\|-*# *$\|# *Usage:\)/q'				\
	 -e '/^#!/d;s/^.*-- */# /;s/^#[ 	]*//p'			\
     < "$script" | fmt
}

help_body ()
{
  $SED -n '/^ *$/q;/^#-/,/^[^#]/s/^#\( \|$\)//p' < "$script"
}

help ()
{
  usage
  short_help
  echo ''
  help_body
}

version ()
{
  local no_nl_vers=`echo "$TLA_TOOLS_VERSION"`
  echo "$me (tla-tools) $no_nl_vers"
  $SED -n '/^[^#]/q;/^#-/q;s/^# *\(Written by\)/\
\1/p' < "$script"
  $SED -n '/^[^#]/q;/^#-/q;s/^# *\(Copyright\)/\
\1/p' < "$script"
}

unrec_opt ()
{
  echo 1>&2 "$me: unrecognized option "\`"$1'"
  echo 1>&2 "Try "\`"$me --help' for more information."
}

cmd_line_err ()
{
  usage 1>&2
  echo 1>&2 "Try "\`"$me --help' for more information."
}

long_opt_val ()
{
  echo "$1" | $SED 's/^[^=]*=//'
}

short_opt_val ()
{
  echo "$1" | $SED 's/^-.//'
}

# (---- end of cmd-line.shpp ----)

case "$1" in
  --help)
    usage
    short_help
    echo ''
    echo "      --help           Display this help message and exit"
    echo "      --version        Display a release identifier string and exit"
    echo ''
    help_body
    exit 0
    ;;
  --version|-V)
    version; exit 0;;
  --)
    shift;;
  -*)
    unrec_opt "$1"; exit 1;;
esac

# (---- end of simple-cmd-line.shpp ----)

test $# -eq 0 || { cmd_line_err; exit 1; }

$AWK '
# return true if REV2 follows REV1
function consecutive_revisions (rev1, rev2  ,pfx1,pfx2,num1,num2)
{
  if (match (rev1, /[0-9]+$/)) {
    pfx1 = substr (rev1, 1, RSTART - 1)
    num1 = substr (rev1, RSTART, RLENGTH) + 0
  } else
    return 0

  if (match (rev2, /[0-9]+$/)) {
    pfx2 = substr (rev2, 1, RSTART - 1)
    num2 = substr (rev2, RSTART, RLENGTH) + 0
  } else
    return 0

  return pfx1 == pfx2 && num1 + 1 == num2
}

BEGIN { cur_entries_sum_line = 0 }

function flush_entries()
{
  if (cur_entries_sum_line) {
    print " * " cur_entries_first_rev

    if (cur_entries_first_rev != cur_entries_last_rev)
      print " - " cur_entries_last_rev

    print cur_entries_sum_line
    print ""

    cur_entries_sum_line = 0
  }
}

# Add REV & SUM_LINE to the current set of entries
function add_entry(rev, sum_line)
{
 if (cur_entries_sum_line						      \
     && (cur_entries_sum_line != sum_line				      \
	 || !consecutive_revisions(cur_entries_last_rev, rev)))
    # This new entry does not fit, flush out all the old entries
    flush_entries()

  if (! cur_entries_sum_line) {
    # Starting a new set of entries
    cur_entries_first_rev = rev
    cur_entries_sum_line = sum_line
  }

  cur_entries_last_rev = rev
}

BEGIN { squash = 0; pending_rev = 0 }

# Beginning of patch-summary list
/^Patches applied:/ { squash = 1 }

# Revision line
squash && /^[ ][*][ ][^@ \/]+@[^@ \/]+--[^@ \/]+\/[^@ \/]+--[^@ \/]+--[^@ \/]+--[^@ \/]+$/ {
  pending_rev = $2
  pending_rev_line = $0
  next
}
# Summary line
squash && pending_rev && /^   [^ ]/ {
  add_entry(pending_rev, $0);
  pending_rev = 0;
  next
}
# Something odd where a summary line should have been
squash && pending_rev {
  flush_entries()
  print pending_rev_line
  pending_rev = 0
  next
}

# Blank separator line
squash && /^ *$/ && cur_entries_sum_line { next }

# Something we do not understand
{ flush_entries(); print }

END { flush_entries() }
'

