diff options
| author | iceyrazor <iceyrazor@mailfence.com> | 2026-02-16 01:31:43 -0600 |
|---|---|---|
| committer | iceyrazor <iceyrazor@mailfence.com> | 2026-02-16 01:31:43 -0600 |
| commit | c3df6bc56e3b7162b68e773be2d717ea0d5cba64 (patch) | |
| tree | e197998e20395f24be5c140ec8f5f3cd0863b545 | |
| parent | 9f6d634e9099bdcf392971195f50db85a38c4933 (diff) | |
quotes
- redid handle vars
- redid ~ and vars
- now parses quotes
| -rw-r--r-- | README.md | 15 | ||||
| -rw-r--r-- | src/lsh_main_func.c | 143 | ||||
| -rwxr-xr-x | src/main.c | 3 |
3 files changed, 132 insertions, 29 deletions
@@ -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; @@ -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); } |
