forked from chuan6/toyshell
-
Notifications
You must be signed in to change notification settings - Fork 0
/
builtin.c
104 lines (95 loc) · 2.12 KB
/
builtin.c
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
104
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "shell.h"
/**
* Builtin commands of the shell
**/
void Builtin_cd(char *ps) {
if (*(ps = Norm(ps)) == '\0') {
printf("Empty path name; working directory is not changed.\n");
return;
}
if (!chdir(ps))
return;
printf("Failed to change working directory to %s\n", ps);
}
void Builtin_alarm(char *s, int *t) {
if (*(s = Norm(s)) == '\0') {
printf("Empty argument; alarm setting unchanged.\n");
return;
}
if (!strcmp(s, "on"))
*t = 1;
else if (!strcmp(s, "off"))
*t = 0;
else
printf("Invalid argument.\n");
}
void Builtin_alias(char *kv, Alias *env) {
char *k;
char *v;
if (*(kv = Norm(kv)) == '\0') {
printf("Empty key-value pair; no alias is added to any command.\n");
return;
}
char *p;
for (p = kv; !isspace(*p) && *p != '\0'; p++)
;
if (*p == '\0') {
printf("Incomplete key-value pair; no alias is added to any command.\n");
return;
}
*p = '\0';
k = kv;
kv = Norm(kv + strlen(kv) + 1);
for (p = kv; !isspace(*p) && *p != '\0'; p++)
;
if (*p == '\0') {
v = kv;
} else {
printf("Too many arguments; no alias is added to any command.\n");
return;
}
if (!strcmp(k, v)) // eliminate useless alias
return;
Alias *ep = NULL; // to point to the first empty element in env
Alias *ap;
int i;
for (i = 0, ap = env; i < NALIAS_MAX; i++, ap++) {
if (ap->key == NULL && ap->val == NULL) {
if (ep == NULL)
ep = ap;
continue;
}
// *ap is not empty
if (!strcmp(k, ap->key)) { // if key exists already, updating instead of adding
//printf("cmp 1\n");
ap->val = v;
return;
}
if (!strcmp(k, ap->val)) { // eliminate tautology
//printf("cmp 2\n");
return;
}
if (!strcmp(v, ap->key) ) { // eliminate chain aliasing
//printf("cmp 3\n");
v = ap->val;
if (ep != NULL)
break;
continue;
}
}
if (ep == NULL) {
printf("Alias container is full; no alias is added to any command.\n");
return;
}
// add the pair to alias
ep->key = (char *)malloc(strlen(k)+1);
strcpy(ep->key, k);
ep->val = (char *)malloc(strlen(v)+1);
strcpy(ep->val, v);
return;
}