Jim Hall [11/4/18 12:49 AM]:

> I'd appreciate a discussion here about these programs and my evaluations
> of their licenses. Especially the ones in red ("no") or yellow
> ("maybe"). Do you agree with the decisions here? What are your thoughts
> on the ones I marked in yellow?

"tail.c" from GNU coreutils - needed just one edit to compile with
OpenWatcom (lines 129-131).
-- 
Hilsen Harald
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

#define MAX_LINE 512
#define PROG "my-tail"

static void usage(FILE *fh);
static int my_fgets(char *s, int n, FILE *io);
int getopt(int argc, char * const argv[], const char *optstring);
static void tail(FILE *fh, int count_wanted);

extern char *optarg;
extern int optind, opterr, optopt;

int
main(int argc, char *argv[])
{
	int c;
	int errflag;
	int count_wanted;
	FILE *fh;
	int i;

	errflag = 0;
	count_wanted = 10;
	opterr = 0;

	while ((c = getopt(argc, argv, ":hc:")) != -1) {
		switch (c) {
		case 'h':
			usage(stdout);
			exit(0);
		case 'c':
			count_wanted = atoi(optarg);
			if (count_wanted == 0) {
				exit(0);
			}
			else if (count_wanted < 0) {
				fprintf(stderr,
					"You can't show negative lines!.\n");
				errflag++;
			}
			break;
		case ':':
			fprintf(stderr,
				"-%c requires a numeric argument.\n",
				optopt);
			errflag++;
			break;
		case '?':
			fprintf(stderr,
				"Unknown option: -%c\n", optopt);
			errflag++;
			break;
		default:
			errflag++;
			break;
		}
	}

	if (errflag) {
		usage(stderr);
		exit(2);
	}

	argc -= optind;
	argv += optind;

	if (argc < 1) {
		tail(stdin, count_wanted);
	}
	else {
		for (i = 0; i < argc; i++) {
			if (strcmp(argv[i], "-") == 0) {
				fh = stdin;
			}
			else {
				fh = fopen(argv[i], "r");
			}

			if (fh == NULL) {
				perror(argv[i]);
				errno = 0;
				continue;
			}
			else {
				tail(fh, count_wanted);
				if (fclose(fh) == EOF) {
					perror(argv[i]);
					errno = 0;
				}
			}
		}
	}

	exit(0);
}

int
my_fgets(char *s, int n, FILE *io)
{
	int c;
	int i;

	i = 0;

	while (--n > 0 && (c = getc(io)) != EOF) {
		if ((s[i++] = c) == '\n') {
			break;
		}
	}
	s[i] = '\0';

	return i;
}

void
tail(FILE *fh, int count_wanted)
{
	char buffer[MAX_LINE];
	int i;
	int current_line = 0;

	/* Now we're ready to declare our faux buffer.
	 * Look, Ma, variable declared arrays.
	 * Needs C99, not supported in OpenWatcom */
	/* char *faux_ring_buffer[count_wanted]; */
	char *faux_ring_buffer[MAX_LINE];
	for (i = 0; i < count_wanted; i++) faux_ring_buffer[i] = NULL;



	/* Read lines. When current_line reaches count_wanted, set
	 * current_line back to 0. By resetting it over and over to 0, we
	 * use it like a Moebius strip. */
	while (my_fgets(buffer, MAX_LINE, fh) > 0) {
		if (current_line == count_wanted) current_line = 0;

		free(faux_ring_buffer[current_line]);
		faux_ring_buffer[current_line] =
		    (char *)malloc(strlen(buffer) + 1);
		if (faux_ring_buffer[current_line] == NULL) {
			fprintf(stderr, "Can't allocate memory! Bu-bye.\n");
			exit(1);
		}
		else {
			strcpy(faux_ring_buffer[current_line], buffer);
			current_line++;
		}
	}

	/* We now have lines in faux_ring_buffer, so we show them. However,
	 * we may not have received as many lines as we hope. So first
	 * check that the pointer isn't NULL, and then print it out. */
	for (i = 0; i < count_wanted; i++, current_line++) {
		if (current_line == count_wanted) current_line = 0;

		if (faux_ring_buffer[current_line] != NULL) {
			fprintf(stdout, "%s",
				faux_ring_buffer[current_line]);
		}
		/* If the line was NULL, the user asked for more lines to
		 * be shown than the file has. To reduce wasted cycles,
		 * adjust i and current_line to minimize the waste to 1. */
		else {
			i = (count_wanted - (current_line + 1));
			current_line = -1;
		}

	}

	for (i = 0; i < count_wanted; i++) free(faux_ring_buffer[i]);
}

static
void usage(FILE *fh)
{
	fprintf(fh, "Usage: %s [-c COUNT] [FILE ...]\n", PROG);
}
_______________________________________________
Freedos-devel mailing list
Freedos-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/freedos-devel

Reply via email to