#!/bin/bash

### Copyright notice at the bottom of this file ###

# $Id: dseq,v 1.17 2011/06/01 23:10:20 adamm Exp $
#
# $Source: /home/adamm/src/dseq/RCS/dseq,v $


export PATH=$($HOME/bin/simplePath)
export PROG=$(basename $0)

export Format='%a %d %b'


main() {
    # Special handling for --help, --man
    if [ "x$1" == "x--man" ] || [ "x$1" == "x--help" ] ; then
	manpage
	exit 0
    fi

    # Default
    inc=1

    # Process options first
    while getopts ":f:i:" opt ; do
	case "$opt" in
	f)  Format="$OPTARG"
	    ;;

	i)  inc=$OPTARG
	    ;;

	*)  printf "%s: illegal option: %s\n\n" $PROG "$OPTARG" 1>&2
	    usage 1>&2
	    exit 1
	    ;;
	esac
    done

    # Then check number/format of the remaining args
    shift $(( $OPTIND - 1 ))
    assertArgsOK "$@"

    # Figure out what we got
    if [ $# -eq 1 ] ; then
	start=$(date '+%Y%m%d')
	num=$1
    else
	start=$1
	num=$2
    fi

    # One last sanity check
    if [ $inc -gt $num ] ; then
	printf "%s: increment (-i %d)" $PROG $inc 1>&2
	printf " must be less than num (%d)\n\n" $num 1>&2
	usage 1>&2
	exit 1
    fi

    # Save any hours/minutes/seconds, because "dateops +n" doesn't
    # preserve them
    len=$(expr "$start" : '[0-9]*')
    if [ $len -gt 8 ] ; then
	set -- $(echo $start | sed 's/\(........\)\(.*\)/\1 \2/')
	start=$1
	hhmmss=$2
    fi

    # Loop de loop!
    d=0
    day=$start
    while [ $d -lt $num ] ; do
	time=$(dateops maketime ${day}${hhmmss})
	edate -t $time "+$Format"
	day=$(dateops +$inc $day)
	d=$(( $d + $inc ))
    done
} # main


assertArgsOK() {
    if [ $# -eq 0 ] || [ $# -gt 2 ] ; then
	printf "%s: expected 1-2 args, got %d\n\n" $PROG $# 1>&2
	usage 1>&2
	exit 1
    fi

    a=1
    err=0
    for arg in "$@" ; do
	if expr "$arg" : '.*[^0-9]' > /dev/null ; then
	    printf "%s: arg %d not numeric: '%s'\n" $PROG $a "$arg" 1>&2
	    err=1
	fi

	a=$(( $a + 1 ))
    done

    if [ $err -gt 0 ] ; then
	exit 1
    fi

    if [ $# -eq 1 ] ; then
	return
    fi

    len=$(expr "$1" : '[0-9]*')
    mod=$(( $len % 2 ))
    if [ $len -lt 8 ] || [ $len -gt 14 ] || [ $mod -eq 1 ] ; then
	printf "%s: arg 1, incorrect length;" $PROG 1>&2
	printf " expected {8,10,12,14}, got %d\n\n" $len 1>&2
	usage 1>&2
	exit 1
    fi
} # assertArgsOK


manpage() {
    cat - <<__EOF
NAME
    dseq -- print sequences of dates

SYNOPSIS
    dseq [ options ] #

    dseq [ options ] start #

DESCRIPTION
    dseq prints sequential list of dates; the default output is:

	Day DD Mon

    which corresponds to "%a %d %b" for strftime(1). The options
    (described below) can be used to change the output and to change the
    interval between the dates printed.

    In the simple case, dseq prints however many dates (one per line)
    are specified by the single numeric argument given on the command
    line.

    By default, the list of dates printed starts with today; a different
    starting date can be given by using the second calling sequence
    (shown above), where "start" is any of YYYYMMDD, YYYYMMDDhh,
    YYYYMMDDhhmm, or YYYYMMDDhhmmss.

OPTIONS
    -f format
	a valid strftime(3) format string (with optional leading "+");
	if given, will be used to format the list of dates

    -i #
	the interval (in days) between dates (default is 1 day)

    --help
    --man
	show this man page

SEE ALSO
    date(1), jot(1), seq(1), strftime(3)

AUTHOR
    Adam Moskowitz <adamm@menlo.com>
__EOF
} # manpage


usage() {
    printf "Usage: $PROG [ -f format ] [ -i # ] [ start ] #\n"
    printf "\n"
    printf "Try $PROG --man for more information\n"
} # usage


main "$@"


###
### Copyright, 2010, Adam Moskowitz. All rights reserved.
###
### Any redistribution of this software must retain the above copyright
### notice, this list of conditions, and the following disclaimer.
###
### Without specific prior written permission from the copyright holder,
### you may not charge a fee for the redistribution of this software.
###
### All other redistribution and use is hereby permitted.
###
### This software is provided "as is" and without any express or implied
### warranties, including, without limitation, the implied warranties of
### merchantability and fitness for a particular purpose.
###
