/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1990-2011 AT&T Intellectual Property *
* and is licensed under the *
* Eclipse Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* release -- list recent release changes
*
* coded for portability
*/
#if _PACKAGE_ast
#include <ast.h>
#include <error.h>
static const char usage[] =
"[-?\n@(#)$Id: release (AT&T Research) 2000-01-28 $\n]"
"[+NAME?release - list recent changes]"
"[+DESCRIPTION?\brelease\b lists the changes within the date range specified"
" by the \b--from\b and \b--to\b options. The input files are assumed to"
" contain date tag lines of the form [\acc\a]]\ayy-mm-dd\a [ \atext\a ]]"
" (or \bdate\b(1) default format), where \acc\a is determined by a Y2K"
" window year of 69 (we can produce an example coding dated 1991 - this"
" can be patented?, how about 1+1=2?.) The date tag lines are followed by"
" \areadme\a text in reverse chronological order (newer entries at the"
" top of the file.) If no selection options are spcified then all"
" changes are listed. If no \afile\a operands are specified then the"
" standard input is read.]"
"[+?The entries for each \afile\a are annotated with the file directory name.]"
"[f:from?Entries older than \adate\a are omitted.]:[date]"
"[r:release?List all changes that include the first \acount\a release marks."
" A release mark has a date tag followed by optional space and at least"
" three \b-\b characters. Changes from release mark \acount\a+1 are not"
" listed. If there are no release marks then the date range is used;"
" if there is at least one release mark then the date range is ignored"
" and at most \acount\a release marks will be listed.]#[count]"
"[t:to?Entries newer than \adate\a are omitted.]:[date]"
"[V?Print the program version and exit.]"
"\n"
"\n[ file ... ]\n"
"\n"
"[+SEE ALSO?\bpackage\b(1)]"
;
#else
#define elementsof(x) ((int)(sizeof(x)/sizeof(x[0])))
#define NiL ((char*)0)
#endif
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#if !_PACKAGE_ast && defined(__STDC__)
#include <stdlib.h>
#include <string.h>
#endif
#if !_PACKAGE_ast
static void
usage()
{
exit(2);
}
#endif
static unsigned long
number(register char* s, char** e)
{
unsigned long q = 0;
while (isspace(*s))
s++;
while (isdigit(*s))
q = q * 10 + *s++ - '0';
if (e)
*e = s;
return q;
}
unsigned long
{
register int i;
register int j;
while (isspace(*s))
s++;
for (i = 0; i < siz; i++)
if (j == (siz - 1))
{
*e = s + siz;
return i / siz + 1;
}
return 0;
}
static unsigned long
date(char* s, char** e)
{
char* t;
unsigned long y;
unsigned long m;
unsigned long d;
if (isdigit(*s))
{
y = number(s, &t);
if (*t != '-')
return 0;
switch (t - s)
{
case 2:
y += 1900;
if (y <= 1969)
y += 100;
break;
case 4:
if (y < 1969)
return 0;
break;
}
if (!(m = number(++t, &s)))
return 0;
if ((s - t) != 2 || *s != '-' || m < 1 || m > 12)
return 0;
if (!(d = number(++s, &t)))
return 0;
if ((t - s) != 2 || d < 1 || d > 31)
return 0;
}
else
{
s = t;
return 0;
if (!(d = number(t, &s)))
return 0;
for (y = 1969; *s; s++)
if ((y = number(s, &t)) && (t - s) == 4)
{
if (y < 1969)
return 0;
break;
}
}
if (e)
{
while (isspace(*t))
t++;
*e = t;
}
return ((y - 1969) * 13 + m) * 32 + d;
}
int
{
register char* s;
register char* u;
register char* v;
char* p;
char* e;
int i;
unsigned long t;
unsigned long lo;
unsigned long hi;
int mk;
FILE* f;
mk = 0;
#if _PACKAGE_ast
for (;;)
{
{
case 'f':
{
return 1;
}
continue;
case 'r':
continue;
case 't':
{
return 1;
}
continue;
case 'V':
return 0;
case '?':
continue;
case ':':
continue;
}
break;
}
if (error_info.errors)
#else
{
if (*(s + 1) == '-')
{
if (!*(s + 2))
{
argv++;
break;
}
usage();
break;
}
for (;;)
{
switch (i = *++s)
{
case 0:
break;
case 'f':
case 't':
if (!*(v = ++s) && !(v = *++argv))
{
s = "??";
continue;
}
if (!(t = date(v, &e)) || *e)
{
return 1;
}
switch (i)
{
case 'f':
lo = t;
break;
case 't':
hi = t;
break;
}
break;
case 'r':
if (!*(v = ++s) && !(v = *++argv))
{
s = "??";
continue;
}
if (*e)
{
return 1;
}
break;
case 'V':
return 0;
default:
/*FALLTHROUGH*/
case '?':
usage();
break;
}
break;
}
}
#endif
do
{
{
argv--;
p = "";
f = stdin;
}
else if (!(f = fopen(p, "r")))
{
return 1;
}
{
if (t = date(s, &e))
{
break;
if (t < lo)
break;
continue;
if (p)
{
if (*p)
{
for (u = v = p; *p; p++)
if (*p == '/')
{
v = u;
u = p + 1;
}
printf("\n:::::::: ");
while ((i = *v++) && i != '/')
printf(" ::::::::\n\n");
}
p = 0;
}
}
if (!p)
}
if (f == stdin)
break;
fclose(f);
} while (*argv);
return 0;
}