aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--5.13.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/5.13.c b/5.13.c
new file mode 100644
index 0000000..f704f53
--- /dev/null
+++ b/5.13.c
@@ -0,0 +1,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;
+}
+