diff options
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | .lush/init.lua | 9 | ||||
| -rw-r--r-- | compile_commands.json | 58 | ||||
| -rw-r--r-- | lib/hashmap/hashmap.c | 69 | ||||
| -rw-r--r-- | lib/hashmap/hashmap.h | 38 | ||||
| -rw-r--r-- | premake5.lua | 4 | ||||
| -rw-r--r-- | src/lua_api.c | 9 | ||||
| -rw-r--r-- | src/lush.c | 81 | ||||
| -rw-r--r-- | src/lush.h | 3 |
9 files changed, 258 insertions, 14 deletions
@@ -3,4 +3,3 @@ Makefile bin obj .cache -vgcore.250513 diff --git a/.lush/init.lua b/.lush/init.lua index 26fe71e..5446dd0 100644 --- a/.lush/init.lua +++ b/.lush/init.lua @@ -25,11 +25,10 @@ lush.setenv("PATH", path) -- the prompt can be customized here too -- %u is username, %h is hostname, %w is current working directory lush.setPrompt("[%u@%h: %w]") --- any global functions that accept either no parameters or just an array of args --- will be read in and stored as built in commands for the shell -function my_command(args) - print("my custom command") -end + +-- aliases can be defined using the alias method by passing the alias name +-- and the command to execute with the alias +lush.alias("h", "help") -- all functions from the Lunar Shell Lua API are available to you to -- customize your startup however you want diff --git a/compile_commands.json b/compile_commands.json index 5ba9a1e..1edddc2 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -5,14 +5,66 @@ "-DLUSH_VERSION=\"0.0.1\"", "-DDEBUG", "-I/usr/include/lua5.4", + "-Ilib/hashmap", + "-g", + "-c", + "-o", + "obj/Debug/hashmap.o", + "lib/hashmap/hashmap.c" + ], + "directory": "/home/lanceb/lush", + "file": "/home/lanceb/lush/lib/hashmap/hashmap.c", + "output": "/home/lanceb/lush/obj/Debug/hashmap.o" + }, + { + "arguments": [ + "/usr/bin/cc", + "-DLUSH_VERSION=\"0.0.1\"", + "-DDEBUG", + "-I/usr/include/lua5.4", + "-Ilib/hashmap", + "-g", + "-c", + "-o", + "obj/Debug/history.o", + "src/history.c" + ], + "directory": "/home/lanceb/lush", + "file": "/home/lanceb/lush/src/history.c", + "output": "/home/lanceb/lush/obj/Debug/history.o" + }, + { + "arguments": [ + "/usr/bin/cc", + "-DLUSH_VERSION=\"0.0.1\"", + "-DDEBUG", + "-I/usr/include/lua5.4", + "-Ilib/hashmap", + "-g", + "-c", + "-o", + "obj/Debug/lua_api.o", + "src/lua_api.c" + ], + "directory": "/home/lanceb/lush", + "file": "/home/lanceb/lush/src/lua_api.c", + "output": "/home/lanceb/lush/obj/Debug/lua_api.o" + }, + { + "arguments": [ + "/usr/bin/cc", + "-DLUSH_VERSION=\"0.0.1\"", + "-DDEBUG", + "-I/usr/include/lua5.4", + "-Ilib/hashmap", "-g", "-c", "-o", "obj/Debug/lush.o", "src/lush.c" ], - "directory": "/home/lanceb/projects/lush", - "file": "/home/lanceb/projects/lush/src/lush.c", - "output": "/home/lanceb/projects/lush/obj/Debug/lush.o" + "directory": "/home/lanceb/lush", + "file": "/home/lanceb/lush/src/lush.c", + "output": "/home/lanceb/lush/obj/Debug/lush.o" } ] diff --git a/lib/hashmap/hashmap.c b/lib/hashmap/hashmap.c new file mode 100644 index 0000000..cfc112c --- /dev/null +++ b/lib/hashmap/hashmap.c @@ -0,0 +1,69 @@ +/* +Copyright (c) 2024, Lance Borden +All rights reserved. + +This software is licensed under the BSD 3-Clause License. +You may obtain a copy of the license at: +https://opensource.org/licenses/BSD-3-Clause + +Redistribution and use in source and binary forms, with or without +modification, are permitted under the conditions stated in the BSD 3-Clause +License. + +THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +*/ + +#include "hashmap.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +hashmap_t *hm_new_hashmap() { + hashmap_t *this = malloc(sizeof(hashmap_t)); + this->cap = 8; + this->len = 0; + // null all pointers in list + this->list = calloc((this->cap), sizeof(map_pair_t *)); + return this; +} + +unsigned int hm_hashcode(hashmap_t *this, char *key) { + unsigned int code; + for (code = 0; *key != '\0'; key++) { + code = *key + 31 * code; + } + + return code % (this->cap); +} + +char *hm_get(hashmap_t *this, char *key) { + map_pair_t *current; + for (current = this->list[hm_hashcode(this, key)]; current; + current = current->next) { + if (strcmp(current->key, key) == 0) { + return current->val; + } + } + // the key is not found + return NULL; +} + +void hm_set(hashmap_t *this, char *key, char *val) { + unsigned int idx = hm_hashcode(this, key); + map_pair_t *current; + for (current = this->list[idx]; current; current = current->next) { + if (strcmp(current->key, key) == 0) { + current->val = val; + return; + } + } + + map_pair_t *p = malloc(sizeof(map_pair_t)); + p->key = key; + p->val = val; + p->next = this->list[idx]; + this->list[idx] = p; + this->len++; +} diff --git a/lib/hashmap/hashmap.h b/lib/hashmap/hashmap.h new file mode 100644 index 0000000..d5775c5 --- /dev/null +++ b/lib/hashmap/hashmap.h @@ -0,0 +1,38 @@ +/* +Copyright (c) 2024, Lance Borden +All rights reserved. + +This software is licensed under the BSD 3-Clause License. +You may obtain a copy of the license at: +https://opensource.org/licenses/BSD-3-Clause + +Redistribution and use in source and binary forms, with or without +modification, are permitted under the conditions stated in the BSD 3-Clause +License. + +THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTIES, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +*/ + +#ifndef HASHMAP_H +#define HASHMAP_H + +typedef struct pair { + char *key; + char *val; + struct pair *next; +} map_pair_t; + +typedef struct { + map_pair_t **list; + unsigned int cap; + unsigned int len; +} hashmap_t; + +hashmap_t *hm_new_hashmap(); +unsigned int hm_hashcode(hashmap_t *this, char *key); +char *hm_get(hashmap_t *this, char *key); +void hm_set(hashmap_t *this, char *key, char *val); + +#endif // HASHMAP_H diff --git a/premake5.lua b/premake5.lua index 34d98dd..1804d09 100644 --- a/premake5.lua +++ b/premake5.lua @@ -18,12 +18,14 @@ else links({ "lua" }) end -includedirs({ lua_inc_path }) +includedirs({ lua_inc_path, "lib/hashmap" }) libdirs({ lua_lib_path }) files({ "src/**.h", "src/**.c", + "lib/hashmap/**.h", + "lib/hashmap/**.c", }) defines({ 'LUSH_VERSION="0.0.1"' }) diff --git a/src/lua_api.c b/src/lua_api.c index 2f967e6..21f5d39 100644 --- a/src/lua_api.c +++ b/src/lua_api.c @@ -325,6 +325,13 @@ static int l_set_prompt(lua_State *L) { return 0; } +static int l_alias(lua_State *L) { + const char *alias = luaL_checkstring(L, 1); + const char *command = luaL_checkstring(L, 2); + lush_add_alias(alias, command); + return 0; +} + // -- register Lua functions -- void lua_register_api(lua_State *L) { @@ -361,6 +368,8 @@ void lua_register_api(lua_State *L) { lua_setfield(L, -2, "unsetenv"); lua_pushcfunction(L, l_set_prompt); lua_setfield(L, -2, "setPrompt"); + lua_pushcfunction(L, l_alias); + lua_setfield(L, -2, "alias"); // set the table as global lua_setglobal(L, "lush"); } @@ -16,6 +16,7 @@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #include "lush.h" +#include "hashmap.h" #include "help.h" #include "history.h" #include "lauxlib.h" @@ -43,6 +44,20 @@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // initialize prompt format char *prompt_format = NULL; +// -- aliasing -- +hashmap_t *aliases = NULL; + +void lush_add_alias(const char *alias, const char *command) { + // make a new map if one doesnt exist + if (aliases == NULL) { + aliases = hm_new_hashmap(); + } + + hm_set(aliases, (char *)alias, (char *)command); +} + +char *lush_get_alias(char *alias) { return hm_get(aliases, alias); } + // -- builtin functions -- char *builtin_strs[] = {"cd", "help", "exit", "time"}; @@ -196,7 +211,8 @@ static char *format_prompt_string(const char *input, const char *username, // Allocate memory for the new string char *result = (char *)malloc(new_size); if (!result) { - return NULL; // Handle memory allocation failure + perror("malloc failed"); + return NULL; } // Replace placeholders in the input string and build the result string @@ -260,6 +276,7 @@ static char *get_prompt() { free(cwd); return prompt; } + size_t get_stripped_length(const char *str) { size_t len = 0; size_t i = 0; @@ -471,6 +488,60 @@ char *lush_read_line() { return buffer; } +// -- static helper for resolving aliases -- +static char *lush_resolve_aliases(char *line) { + // Allocate memory for the new string + char *result = (char *)malloc(BUFFER_SIZE); + if (!result) { + perror("malloc failed"); + return NULL; + } + + // Create a copy of the input line for tokenization + char *line_copy = strdup(line); + if (!line_copy) { + perror("strdup failed"); + free(result); + return NULL; + } + + // Start building the result string + char *dest = result; + char *arg = strtok(line_copy, " "); + while (arg != NULL) { + // Check shell aliases + if (aliases != NULL) { + char *alias = hm_get(aliases, arg); + if (alias != NULL) { + // Replace alias + strcpy(dest, alias); + dest += strlen(alias); + } else { + // No alias found, use the original token + strcpy(dest, arg); + dest += strlen(arg); + } + } else { + // No aliases set, just use the original token + strcpy(dest, arg); + dest += strlen(arg); + } + + // Add a space after each token (if it's not the last one) + arg = strtok(NULL, " "); + if (arg != NULL) { + *dest++ = ' '; + } + } + + *dest = '\0'; // Null-terminate the result string + + // Clean up + free(line_copy); + + return result; +} + char **lush_split_pipes(char *line) { char **commands = calloc(16, sizeof(char *)); if (!commands) { @@ -685,7 +756,6 @@ int lush_run(lua_State *L, char ***commands, int num_commands) { return ((*builtin_func[i])(L, commands)); } } - return lush_execute_pipeline(commands, num_commands); } @@ -722,7 +792,8 @@ int main(int argc, char *argv[]) { free(line); continue; } - char **commands = lush_split_pipes(line); + char *expanded_line = lush_resolve_aliases(line); + char **commands = lush_split_pipes(expanded_line); char ***args = lush_split_args(commands, &status); if (status == -1) { fprintf(stderr, "lush: Expected end of quoted string\n"); @@ -737,11 +808,13 @@ int main(int argc, char *argv[]) { free(prompt); free(args); free(commands); + free(expanded_line); free(line); } lua_close(L); if (prompt_format != NULL) free(prompt_format); - + if (aliases != NULL) + free(aliases); return 0; } @@ -20,6 +20,9 @@ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. #include <lua.h> +void lush_add_alias(const char *alias, const char *command); +char *lush_get_alias(char *alias); + int lush_cd(lua_State *L, char ***args); int lush_help(lua_State *L, char ***args); int lush_exit(lua_State *L, char ***args); |
