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
[email protected]
https://lists.sourceforge.net/lists/listinfo/freedos-devel