aboutsummaryrefslogtreecommitdiff
path: root/5.13.c
blob: f704f53a27aa088679b14f56fd022d59a2c1030c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*****************************************************************************

tail

DESCRIPTION: tail prints the last -n lines of a input, if n is not give it 
prints 10 lines by default, no malloc or stcpy is used in this version and 
stack storage is allocated in the most efficent way for each line

*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define DEFAULT_N 10
#define MAXLEN 1000
#define MAXLINE 5000
#define BUFFSIZE MAXLEN * MAXLINE

char buff[BUFFSIZE];
char *lineptr[MAXLINE];
int buff_now;
int lineptr_now;
int line_no;

void get_tail(void);
int sneed_getline(char str[], int max);
void pr_tail(int nlines);

int 
main(int argc, char **argv)
{
  int nlines = 0;

  if (--argc == 1 && **(++argv) == '-' && isdigit(*++*argv)) {
    for (; isdigit(**argv) ; ++*argv)
      nlines = nlines * 10 + **argv - '0';
  } 
  
  else if (argc != 0)
    argc = -1;

    
  if (!nlines)
    nlines = DEFAULT_N;

  if ( argc >= 0 && nlines > 0 && nlines < MAXLINE) {
    get_tail();
    pr_tail(nlines);
  }

  else 
    printf("Usage: tail -n\n");
}

void 
get_tail(void) {
  int len;

  while ((len = sneed_getline(buff + buff_now, MAXLEN)) > 0) {

    lineptr[lineptr_now] = buff + buff_now ;
    line_no++;
    
    buff_now = (buff_now + MAXLEN >= BUFFSIZE -1) ? 0 : buff_now + len + 1;
    lineptr_now = (lineptr_now >= MAXLINE - 1) ? 0 : lineptr_now + 1;
  }
}

void
pr_tail(int nlines)
{
  if (line_no < nlines)
    nlines = line_no;

  lineptr_now = (lineptr_now - nlines < 0) ? MAXLINE - 1 + lineptr_now - nlines : lineptr_now - nlines;

  while(nlines--) {
    printf("%s", lineptr[lineptr_now]);
    lineptr_now = (lineptr_now >= MAXLINE - 1) ? 0 : lineptr_now + 1;
  }
}

int 
sneed_getline(char str[], int max)
{
  char input;
  char *str_og;

  str_og = str;

  --max;
  while (--max && (input = getchar()) != EOF && input != '\n')
    *str++ = input;

  if (input == '\n' && max)
    *str++ = input;

  *str = '\0';

  return str - str_og;
}