forked from vsinha/shell
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshell.l
More file actions
166 lines (121 loc) · 2.91 KB
/
shell.l
File metadata and controls
166 lines (121 loc) · 2.91 KB
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
*
* CS-252 Fall 2013
* shell.l: lexical analyzer for shell
* You have to extend it.
*
*/
%{
#include <regex.h>
#include <string.h>
#include <unistd.h>
#include "read-line.h"
#include "shell.tab.h"
#include "trace.h"
static void yyunput (int c, char *buf_ptr);
void myunputc(int c) {
unput(c);
}
// code for readline
int mygetc( FILE * f ) {
static char *p;
char ch;
if ( !isatty(0) ) {
//stdin is not a tty, call real getc
return getc(f);
}
//stdin is a tty, call our read_line
if ( p == NULL || *p == 0 ) {
char * s = read_line();
p = s;
}
ch = *p;
p++;
return ch;
}
#undef getc
#define getc(f) mygetc(f)
// end code for readline
%}
%%
\n { return NEWLINE; }
";" { return NEWLINE; }
[ \t] { /* Discard spaces and tabs */ }
">" { return GREAT; }
">>" { return GREATGREAT; }
">&" { return GREATAMPERSAND; }
">>&" { return GREATGREATAMPERSAND; }
"<" { return LESS; }
"|" { return PIPE; }
"&" { return AMPERSAND; }
/*
\`[^\n\`]*\` {
// handle ` marks for subshell expansion...
char * subs = strdup(yytext + 1); // drop the front tic
subs[ strlen(subs) - 1] = '\0'; // drop the end tick
// put subs into a buffer
// redirect stdin of child to read from subs buffer
// redirect stdout of child to unput into original stdin of parent
// fork
pid_t child;
child = fork();
if ( child == 0 ) {
// set stdout to the pipe
// call main
main();
}
yylval.string_val = strdup(yytext);
return WORD;
}
*/
\"[^\n\"]*\" {
/* handle arguments in quotes by stripping the quotes */
yytext = (char*)(yytext+1); // drop the front quotes
yytext[ strlen(yytext) - 1 ] = '\0'; // drop the end quotes
yylval.string_val = strdup(yytext);
return WORD;
}
[^ \t\n][^ \t\n]* {
//create regex
regex_t preg;
regmatch_t match;
const char * pattern = "[>|<|\\|]"; // match >, <, or |
if ( regcomp(&preg, pattern, 0) ) {
perror ("regex failed to compile");
exit(1);
}
// if we encounter > or |, unput all the characters in reverse order
if ( !regexec(&preg, yytext, 1, &match, 0) ) {
TRACE("preg = %d\n", match.rm_so);
char * temp = (char*)malloc( strlen(yytext) * sizeof(char) );
temp[0] = '\0'; // add a null terminator
// copy until our special character
strncat( temp, yytext, match.rm_so * sizeof(char) );
TRACE("temp: %s\n", temp);
int i;
int m = 0;
// iterate backwards until we reach the regex'd character
for ( i = strlen(yytext) - 1; i >= match.rm_so; i-- ) {
TRACE("i: %d, m: %d\n", i, m);
if ( i == match.rm_so ) {
char c = yytext[i];
TRACE("unputting space\n");
myunputc(' ');
TRACE("unputting %c\n", c);
myunputc(c);
} else {
TRACE("unputting %c\n", yytext[i]);
myunputc(yytext[i]);
}
m++;
if (m > 10) {
TRACE("exit because lol\n");
exit(1);
} // loooop
}
yytext = temp;
}
yylval.string_val = strdup(yytext);
return WORD;
}
%%