aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md15
-rw-r--r--src/lsh_main_func.c143
-rwxr-xr-xsrc/main.c3
3 files changed, 132 insertions, 29 deletions
diff --git a/README.md b/README.md
index d7000f8..40f4048 100644
--- a/README.md
+++ b/README.md
@@ -5,25 +5,30 @@ Going to try and make it mostly POSIX compliant.
## todo
-- [ ] rewrite handle arg function. tis bad pointer stuff
-- [x] environment variables
+- [x] rewrite handle arg function. tis bad pointer stuff
- [x] custom prompts
-- [ ] fix prompt to use PS1 environment variable
- [x] minimal current directory
-- [ ] handle ~
+- [x] handle ~
- [ ] dynamically allocate cwd in cd builtin command
- [ ] history
- [ ] cursor movement
- [ ] tab to autocomplete files and dirs
- [ ] all of posixsxssssss
- [ ] aliases
+ - [x] $vars
+ - [ ] make them more than space delimited
- [x] increase the SHLVL var
- [x] update pwd
- - [ ] quotes
+ - [x] quotes
+ - [ ] single quotes
+ - [ ] prompt uses PS1
- [ ] pipes |
+ - [ ] &&
+ - [ ] ;
- [ ] vi mode
- [ ] redirections > <
- [ ] append >>
- [ ] heredoc
+ - [ ] &
- [ ] rcfile
- [ ] rcfile in config dir
diff --git a/src/lsh_main_func.c b/src/lsh_main_func.c
index fdaa011..9864b20 100644
--- a/src/lsh_main_func.c
+++ b/src/lsh_main_func.c
@@ -6,6 +6,7 @@
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <stdbool.h>
#define LSH_RL_BUFSIZE 1024
char *lsh_read_line(void)
@@ -45,38 +46,132 @@ char *lsh_read_line(void)
}
}
-//this needs to be rewritten/moved for better memory management. eg not writing to getenv or a pointer to a string that must not be modified
-//eg dont use token=some pointer
char *handle_vars(char *token){
- token=&token[0];
- if (token[0] == '$'){
- token=&token[1];
- if(getenv(token)){
- token=getenv(token);
- } else {
- token="";
+ char *ret_token=(char*)malloc(sizeof(char)*strlen(token)+1);
+ strcpy(ret_token,token);
+
+ if (token[0]=='~'){
+ token++;
+ if(!getenv("HOME")){
+ fprintf(stderr,"lsh: you aint got no home. da hell\n");
+ free(ret_token);
+ ret_token=(char*)malloc(sizeof(char)*strlen(token)+1);
+ strcpy(ret_token,token);
+ return ret_token;
}
+ free(ret_token);
+ ret_token=(char*)malloc(sizeof(char)*strlen(token)+strlen(getenv("HOME"))+1);
+ strcpy(ret_token,getenv("HOME"));
+ strcat(ret_token,token);
}
- /*
- if (token[0] == '~'){
- token=&token[1];
- char *orig = (char*)malloc(sizeof(char) * ( strlen(token) + strlen(getenv("HOME") + 1)));
- strcpy(orig,token);
- strcpy(token,getenv("home")) has a weird doubling memory thing i dont understand
- strcpy(token,getenv("HOME"));
+ char *tmp_token=(char*)malloc(sizeof(char)*strlen(ret_token)+1);
+ strcpy(tmp_token,ret_token);
+ int i=0;
+ while (tmp_token[i]!='\0'){
+ if(tmp_token[i]=='$'){
+ int j=0; while(tmp_token[i+j]!=' ' && tmp_token[i+j]) j++;
+
+ char *varname=(char*)malloc(sizeof(char)*j+1);
+ varname[j]='\0';
+ strncpy(varname,&tmp_token[i+1],j);
+ varname[j-1]='\0';
+
+ char *env = getenv(varname);
+ if(!env){
+ env="";
+ }
+
+ free(ret_token);
+ int tmp_len=strlen(tmp_token);
+ ret_token=(char*)malloc(sizeof(char)*(strlen(tmp_token)-strlen(varname))+strlen(env)+1);
+ tmp_token[i]='\0';
+ tmp_token[i+j]='\0';
+
+ strcpy(ret_token,tmp_token);
+ strcat(ret_token,env);
+ strcat(ret_token," ");
+ if(i+j+1 < tmp_len){
+ strcat(ret_token,&tmp_token[i+j+1]);
+ }
+
+ free(tmp_token);
+ tmp_token=(char*)malloc(sizeof(char)*strlen(ret_token)+1);
+ strcpy(tmp_token,ret_token);
+
+ free(varname);
+ }
+ i++;
+ }
+ free(tmp_token);
+ return ret_token;
+}
- strcat(token,orig);
- printf("TOK: %s\n\n",token);
- free(orig);
+char * strtok_quotes(char *token){
+ static char* parse_args_last_p;
+ if(token != NULL){
+ parse_args_last_p=token;
+ }
+ if(parse_args_last_p==NULL){
+ return NULL;
}
- */
- return token;
+ char *return_char=parse_args_last_p;
+ bool in_quote=false;
+
+ if(parse_args_last_p != NULL){
+ int ch_i=0;
+ while(1){
+ if (parse_args_last_p[ch_i] == '\0')
+ break;
+
+ if (in_quote==false&parse_args_last_p[ch_i]=='"'){
+ bool pass_check=true;
+ if(ch_i>0 && parse_args_last_p[ch_i-1]=='\\')
+ pass_check=false;
+
+ if(pass_check==true){
+ parse_args_last_p[ch_i]='\0';
+ if (parse_args_last_p[ch_i+1] == '\0')
+ break;
+ return_char = &return_char[1];
+ ch_i++;
+ in_quote=true;
+ }
+ }
+
+ if(in_quote==true){
+ if (parse_args_last_p[ch_i]=='"'){
+ bool pass_check=true;
+ if(ch_i>0 && parse_args_last_p[ch_i-1]=='\\')
+ pass_check=false;
+
+ if(pass_check==true){
+ if(parse_args_last_p[ch_i+1]=='\0')
+ parse_args_last_p[ch_i]='\0';
+ else if(parse_args_last_p[ch_i+1]==' '){
+ parse_args_last_p[ch_i]='\0';
+ parse_args_last_p = &parse_args_last_p[ch_i+2];
+ return return_char;
+ }
+ in_quote=false;
+ }
+ }
+ } else {
+ if (parse_args_last_p[ch_i] == ' '){
+ parse_args_last_p[ch_i] = '\0';
+ parse_args_last_p = &parse_args_last_p[ch_i+1];
+ return return_char;
+ }
+ }
+ ch_i++;
+ }
+ parse_args_last_p=NULL;
+ }
+ return return_char;
}
#define LSH_TOK_BUFSIZE 64
-#define LSH_TOK_DELIM " \t\r\n\a"
char **lsh_split_line(char *line)
{
int bufsize = LSH_TOK_BUFSIZE, position = 0;
@@ -88,7 +183,7 @@ char **lsh_split_line(char *line)
exit(EXIT_FAILURE);
}
- token = strtok(line, LSH_TOK_DELIM);
+ token = strtok_quotes(line);
while (token != NULL) {
token = handle_vars(token);
tokens[position] = token;
@@ -104,7 +199,7 @@ char **lsh_split_line(char *line)
}
}
- token = strtok(NULL, LSH_TOK_DELIM);
+ token = strtok_quotes(NULL);
}
tokens[position] = NULL;
return tokens;
diff --git a/src/main.c b/src/main.c
index 15830ac..262c504 100755
--- a/src/main.c
+++ b/src/main.c
@@ -29,6 +29,9 @@ void lsh_loop(SHELL_OB *shell_obj)
status = lsh_execute(args);
free(line);
+ int i=0;
+ while (args[i])
+ free(args[i++]);
free(args);
} while (status);
}