1
+ #include " /include/io"
2
+ #include " /include/fs"
3
+ #include " /include/memory"
4
+ #include " /include/shell"
5
+ #include " /include/string"
6
+ #include " /include/xtoa_atoi"
7
+ struct string {
8
+ char *text;
9
+ int capacity;
10
+ int length;
11
+ };
12
+ string new_string () {
13
+ string s;
14
+ s.text = malloc (16 );
15
+ s.capacity = 16 ;
16
+ s.length = 0 ;
17
+ return s;
18
+ }
19
+ struct node {
20
+ string text;
21
+ node *prev;
22
+ node *next;
23
+ };
24
+ void destroy (node *tmp) {
25
+ free (tmp->text .text );
26
+ free (tmp);
27
+ }
28
+ void push (node **head, node **last, string s, int not_remove) {
29
+ node *new_node = (node *) malloc (sizeof (node));
30
+ new_node->text = s;
31
+ new_node->prev = 0 ;
32
+ new_node->next = *head;
33
+ if (new_node->next )
34
+ new_node->next ->prev = new_node;
35
+ if (not_remove == 1 ) {
36
+ if (!*last)
37
+ *last = new_node;
38
+ } else {
39
+ node *tmp = *last;
40
+ destroy (tmp);
41
+ *last = (*last)->prev ;
42
+ (*last)->next = 0 ;
43
+ }
44
+ *head = new_node;
45
+ }
46
+ void append_char (string *s, char c) {
47
+ if (s->length >= s->capacity - 1 ) {
48
+ s->capacity <<= 1 ;
49
+ char *new_text = malloc (s->capacity );
50
+ strcpy (new_text, s->text );
51
+ free (s->text );
52
+ s->text = new_text;
53
+ }
54
+ (s->text )[s->length ++] = c;
55
+ (s->text )[s->length ] = 0 ;
56
+ }
57
+ void print (node *last) {
58
+ while (last) {
59
+ put_string ((last->text ).text );
60
+ put_string (" \n " );
61
+ last = last->prev ;
62
+ }
63
+ }
64
+ void tail (int n) {
65
+ int c, i = 0 , cmd = 0 ;
66
+ node *list = (node *) 0 ;
67
+ node *last = (node *) 0 ;
68
+ string s = new_string ();
69
+ input_lock ();
70
+ while ((c = input_char ()) != -1 ) {
71
+ if (((char ) c) == ' \033 ' ) {
72
+ append_char (&s, c);
73
+ cmd = 1 - cmd;
74
+ } else if (cmd == 0 ) {
75
+ if (((char ) c) == ' \n ' ) {
76
+ push (&list, &last, s, i < n);
77
+ s = new_string ();
78
+ ++i;
79
+ } else {
80
+ append_char (&s, c);
81
+ }
82
+ } else {
83
+ append_char (&s, c);
84
+ }
85
+ }
86
+ push (&list, &last, s, i < n);
87
+ input_unlock ();
88
+ print (last);
89
+ }
90
+ int main (int argc, char **argv) {
91
+ if (argc == 1 ) { // tail
92
+ shell (" pipe" );
93
+ } else if (argc == 2 ) { // tail XX
94
+ int n = atoi32 (argv[1 ]);
95
+ if (n <= 0 )
96
+ return 1 ;
97
+ tail (n);
98
+ } else {
99
+ set_fg (240 , 0 , 0 );
100
+ put_string (" [Error] Invalid argument." );
101
+ restore_fg ();
102
+ }
103
+ return 0 ;
104
+ }
0 commit comments