/*
 * looptest.c - loop iteration tester
 */
/*-
 * Copyright (c) 2008-2018
 *	Jeffrey Allen Neitzel <jan (at) v6shell (dot) org>.
 *	All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY JEFFREY ALLEN NEITZEL ``AS IS'', AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL JEFFREY ALLEN NEITZEL BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *	@(#)$Id: c0c047310342a08bc8370b786293448bdbc18d80 $
 */

#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#ifndef	lint
#ifndef	LT_ATTR
# if __GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 4
#  define	LT_ATTR		__attribute__((__used__))
# elif defined(__GNUC__)
#  define	LT_ATTR		__attribute__((__unused__))
# else
#  define	LT_ATTR		/* nothing */
# endif
#endif	/* !LT_ATTR */

/*@unused@*/
static const char *const vcid[] LT_ATTR = {
	"\100(#)\044Id: " LT_VERSION " \044",
	"\100(#)\044Id: Copyright (c) 2008-2018 Jeffrey Allen Neitzel. \044"
};
#endif	/* !lint */

#define	MYNAME	"unknown"

/*@observer@*/
static	const char	*myname = NULL;

static	void	setmyname(/*@null@*/ const char *);

/*
 * NAME
 *	looptest - loop iteration tester
 *
 * SYNOPSIS
 *	looptest count file
 *
 * DESCRIPTION
 *	See the looptest(1) manual page for full details.
 */
int
main(int argc, char *const *argv)
{
	unsigned long count, lines;
	int c;
	char *nbad;

	setmyname(argv[0]);

	if (argc != 3 || *argv[1] < '0' || *argv[1] > '9') {
		(void)fprintf(stderr, "usage: %s count file\n", myname);
		return 2;
	}

	(void)close(STDIN_FILENO);
	if (open(argv[2], O_RDONLY) != STDIN_FILENO) {
		(void)fprintf(stderr, "%s: %s: cannot open\n", myname, argv[2]);
		return 2;
	}

	errno = 0;
	count = strtoul(argv[1], &nbad, 10);
	if (*nbad != '\0' || (errno == ERANGE && count == ULONG_MAX)) {
		(void)fprintf(stderr, "%s: %s: bad count\n", myname, argv[1]);
		return 2;
	}

	lines = 0;
	while ((c = getchar()) != EOF) {
		while (c != '\n' && c != EOF)
			c = getchar();
		if (c == EOF)
			break;
		if (c == '\n')
			lines++;
	}

	return (lines == count) ? 0 : 1;
}

/*
 * Set the global myname to the basename of the string pointed to by s.
 */
static void
setmyname(const char *s)
{
	const char *p;

	if (s != NULL && *s != '\0') {
		if ((p = strrchr(s, '/')) != NULL)
			p++;
		else
			p = s;
	} else
		/* should never (but can) be true */
		p = MYNAME;

	myname = p;
}
