Blame src/cmd/INIT/release.c

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