From 86f96ee350cb39c026bb2da3c96cf3e64f458038 Mon Sep 17 00:00:00 2001 From: marcusDenslow Date: Wed, 27 Aug 2025 20:47:44 +0200 Subject: [PATCH] added this file --- aliases.c | 813 +++++++++++++++++++++++++++--------------------------- 1 file changed, 409 insertions(+), 404 deletions(-) diff --git a/aliases.c b/aliases.c index 0f3be50..3e6ea08 100644 --- a/aliases.c +++ b/aliases.c @@ -1,6 +1,6 @@ /** * aliases.c - * Implementation of shell alias functionality + * Implementation of shell alias functionality this is a test */ #include "aliases.h" @@ -21,496 +21,501 @@ char aliases_file_path[PATH_MAX]; * Initialize the alias system */ void init_aliases(void) { - // Set initial capacity - alias_capacity = 10; - aliases = (AliasEntry*)malloc(alias_capacity * sizeof(AliasEntry)); - - if (!aliases) { - fprintf(stderr, "lsh: allocation error in init_aliases\n"); - return; - } - - // Determine aliases file location - in user's home directory - char *home_dir = getenv("HOME"); - if (home_dir) { - snprintf(aliases_file_path, PATH_MAX, "%s/.lsh_aliases", home_dir); - } else { - // Fallback to current directory if HOME not available - strcpy(aliases_file_path, ".lsh_aliases"); - } - - // Load aliases from file - load_aliases(); + // Set initial capacity + alias_capacity = 10; + aliases = (AliasEntry *)malloc(alias_capacity * sizeof(AliasEntry)); + + if (!aliases) { + fprintf(stderr, "lsh: allocation error in init_aliases\n"); + return; + } + + // Determine aliases file location - in user's home directory + char *home_dir = getenv("HOME"); + if (home_dir) { + snprintf(aliases_file_path, PATH_MAX, "%s/.lsh_aliases", home_dir); + } else { + // Fallback to current directory if HOME not available + strcpy(aliases_file_path, ".lsh_aliases"); + } + + // Load aliases from file + load_aliases(); } /** * Clean up the alias system */ void cleanup_aliases(void) { - if (!aliases) return; - - // Free all alias entries - for (int i = 0; i < alias_count; i++) { - free(aliases[i].name); - free(aliases[i].command); - } - - // Free the array - free(aliases); - aliases = NULL; - alias_count = 0; - alias_capacity = 0; + if (!aliases) + return; + + // Free all alias entries + for (int i = 0; i < alias_count; i++) { + free(aliases[i].name); + free(aliases[i].command); + } + + // Free the array + free(aliases); + aliases = NULL; + alias_count = 0; + alias_capacity = 0; } /** * Shutdown the alias system */ void shutdown_aliases(void) { - // Clean up (don't save here since we save immediately on changes) - cleanup_aliases(); + // Clean up (don't save here since we save immediately on changes) + cleanup_aliases(); } /** * Load aliases from file */ int load_aliases(void) { - FILE *fp = fopen(aliases_file_path, "r"); - if (!fp) { - return 0; // File doesn't exist or can't be opened + FILE *fp = fopen(aliases_file_path, "r"); + if (!fp) { + return 0; // File doesn't exist or can't be opened + } + + // Set loading flag to prevent saving during loading + loading_aliases = 1; + + char line[LSH_RL_BUFSIZE]; + char name[LSH_RL_BUFSIZE / 2]; + char command[LSH_RL_BUFSIZE / 2]; + + while (fgets(line, sizeof(line), fp)) { + // Skip comments and empty lines + if (line[0] == '#' || line[0] == '\n') { + continue; } - - // Set loading flag to prevent saving during loading - loading_aliases = 1; - - char line[LSH_RL_BUFSIZE]; - char name[LSH_RL_BUFSIZE / 2]; - char command[LSH_RL_BUFSIZE / 2]; - - while (fgets(line, sizeof(line), fp)) { - // Skip comments and empty lines - if (line[0] == '#' || line[0] == '\n') { - continue; - } - - // Parse alias definitions (name=command) - char *equals = strchr(line, '='); - if (equals) { - *equals = '\0'; - char *line_name = line; - char *line_command = equals + 1; - - // Remove newline from command if present - char *newline = strchr(line_command, '\n'); - if (newline) { - *newline = '\0'; - } - - // Trim whitespace - while (*line_name == ' ' || *line_name == '\t') line_name++; - while (*line_command == ' ' || *line_command == '\t') line_command++; - - if (*line_name && *line_command) { - add_alias(line_name, line_command); - } - } + + // Parse alias definitions (name=command) + char *equals = strchr(line, '='); + if (equals) { + *equals = '\0'; + char *line_name = line; + char *line_command = equals + 1; + + // Remove newline from command if present + char *newline = strchr(line_command, '\n'); + if (newline) { + *newline = '\0'; + } + + // Trim whitespace + while (*line_name == ' ' || *line_name == '\t') + line_name++; + while (*line_command == ' ' || *line_command == '\t') + line_command++; + + if (*line_name && *line_command) { + add_alias(line_name, line_command); + } } - - // Clear loading flag - loading_aliases = 0; - - fclose(fp); - return 1; + } + + // Clear loading flag + loading_aliases = 0; + + fclose(fp); + return 1; } /** * Save aliases to file */ int save_aliases(void) { - FILE *fp = fopen(aliases_file_path, "w"); - if (!fp) { - fprintf(stderr, "lsh: error saving aliases to %s\n", aliases_file_path); - return 0; - } - - // Write file header - time_t t = time(NULL); - struct tm *tm_info = localtime(&t); - char timestamp[26]; - strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", tm_info); - - fprintf(fp, "# LSH Aliases - Last updated: %s\n\n", timestamp); - - // Write each alias - for (int i = 0; i < alias_count; i++) { - fprintf(fp, "%s=%s\n", aliases[i].name, aliases[i].command); - } - - fclose(fp); - return 1; + FILE *fp = fopen(aliases_file_path, "w"); + if (!fp) { + fprintf(stderr, "lsh: error saving aliases to %s\n", aliases_file_path); + return 0; + } + + // Write file header + time_t t = time(NULL); + struct tm *tm_info = localtime(&t); + char timestamp[26]; + strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", tm_info); + + fprintf(fp, "# LSH Aliases - Last updated: %s\n\n", timestamp); + + // Write each alias + for (int i = 0; i < alias_count; i++) { + fprintf(fp, "%s=%s\n", aliases[i].name, aliases[i].command); + } + + fclose(fp); + return 1; } /** * Add a new alias */ int add_alias(const char *name, const char *command) { - if (!name || !command) { - return 0; - } - - // Check if alias already exists, update it if it does - for (int i = 0; i < alias_count; i++) { - if (strcmp(aliases[i].name, name) == 0) { - // Update existing alias - free(aliases[i].command); - aliases[i].command = strdup(command); - // Save aliases immediately after updating (unless loading) - if (!loading_aliases) { - save_aliases(); - } - return 1; - } - } - - // Check if we need to expand the array - if (alias_count >= alias_capacity) { - alias_capacity *= 2; - AliasEntry *new_aliases = (AliasEntry*)realloc(aliases, alias_capacity * sizeof(AliasEntry)); - if (!new_aliases) { - fprintf(stderr, "lsh: allocation error in add_alias\n"); - return 0; - } - aliases = new_aliases; - } - - // Add new alias - aliases[alias_count].name = strdup(name); - aliases[alias_count].command = strdup(command); - alias_count++; - - // Save aliases immediately after adding (unless loading) - if (!loading_aliases) { + if (!name || !command) { + return 0; + } + + // Check if alias already exists, update it if it does + for (int i = 0; i < alias_count; i++) { + if (strcmp(aliases[i].name, name) == 0) { + // Update existing alias + free(aliases[i].command); + aliases[i].command = strdup(command); + // Save aliases immediately after updating (unless loading) + if (!loading_aliases) { save_aliases(); + } + return 1; } - - return 1; + } + + // Check if we need to expand the array + if (alias_count >= alias_capacity) { + alias_capacity *= 2; + AliasEntry *new_aliases = + (AliasEntry *)realloc(aliases, alias_capacity * sizeof(AliasEntry)); + if (!new_aliases) { + fprintf(stderr, "lsh: allocation error in add_alias\n"); + return 0; + } + aliases = new_aliases; + } + + // Add new alias + aliases[alias_count].name = strdup(name); + aliases[alias_count].command = strdup(command); + alias_count++; + + // Save aliases immediately after adding (unless loading) + if (!loading_aliases) { + save_aliases(); + } + + return 1; } /** * Remove an alias */ int remove_alias(const char *name) { - if (!name) { - return 0; + if (!name) { + return 0; + } + + for (int i = 0; i < alias_count; i++) { + if (strcmp(aliases[i].name, name) == 0) { + // Free memory for this alias + free(aliases[i].name); + free(aliases[i].command); + + // Shift remaining aliases down + for (int j = i; j < alias_count - 1; j++) { + aliases[j] = aliases[j + 1]; + } + + alias_count--; + // Save aliases immediately after removing (unless loading) + if (!loading_aliases) { + save_aliases(); + } + return 1; } - - for (int i = 0; i < alias_count; i++) { - if (strcmp(aliases[i].name, name) == 0) { - // Free memory for this alias - free(aliases[i].name); - free(aliases[i].command); - - // Shift remaining aliases down - for (int j = i; j < alias_count - 1; j++) { - aliases[j] = aliases[j + 1]; - } - - alias_count--; - // Save aliases immediately after removing (unless loading) - if (!loading_aliases) { - save_aliases(); - } - return 1; - } - } - - return 0; // Alias not found + } + + return 0; // Alias not found } /** * Find an alias by name */ -AliasEntry* find_alias(const char *name) { - for (int i = 0; i < alias_count; i++) { - if (strcmp(aliases[i].name, name) == 0) { - return &aliases[i]; - } +AliasEntry *find_alias(const char *name) { + for (int i = 0; i < alias_count; i++) { + if (strcmp(aliases[i].name, name) == 0) { + return &aliases[i]; } - return NULL; + } + return NULL; } /** * Expand a command line by replacing aliases */ -char* expand_aliases(const char *command) { - if (!command) { - return NULL; - } - - char *result = strdup(command); - if (!result) return NULL; - - // Copy the command for tokenization - char *cmd_copy = strdup(result); - if (!cmd_copy) { - free(result); - return NULL; - } - - // Extract the first word (command name) - char *token = strtok(cmd_copy, " \t"); - if (!token) { - free(cmd_copy); - return result; - } - - // Look up the alias - AliasEntry *alias = find_alias(token); - if (alias) { - // Get the args after the command - char *args = strchr(command, ' '); - - // Allocate new buffer for expanded command - free(result); - if (args) { - // Concatenate alias command and original args - result = malloc(strlen(alias->command) + strlen(args) + 1); - if (result) { - strcpy(result, alias->command); - strcat(result, args); - } - } else { - // No args, just use alias command - result = strdup(alias->command); - } - } - +char *expand_aliases(const char *command) { + if (!command) { + return NULL; + } + + char *result = strdup(command); + if (!result) + return NULL; + + // Copy the command for tokenization + char *cmd_copy = strdup(result); + if (!cmd_copy) { + free(result); + return NULL; + } + + // Extract the first word (command name) + char *token = strtok(cmd_copy, " \t"); + if (!token) { free(cmd_copy); return result; + } + + // Look up the alias + AliasEntry *alias = find_alias(token); + if (alias) { + // Get the args after the command + char *args = strchr(command, ' '); + + // Allocate new buffer for expanded command + free(result); + if (args) { + // Concatenate alias command and original args + result = malloc(strlen(alias->command) + strlen(args) + 1); + if (result) { + strcpy(result, alias->command); + strcat(result, args); + } + } else { + // No args, just use alias command + result = strdup(alias->command); + } + } + + free(cmd_copy); + return result; } /** * Command handler for the "alias" command */ int lsh_alias(char **args) { - // No arguments - list all aliases - if (args[1] == NULL) { - for (int i = 0; i < alias_count; i++) { - printf("alias %s='%s'\n", aliases[i].name, aliases[i].command); - } - return 1; + // No arguments - list all aliases + if (args[1] == NULL) { + for (int i = 0; i < alias_count; i++) { + printf("alias %s='%s'\n", aliases[i].name, aliases[i].command); } - - // Pre-defined aliases - if (strcmp(args[1], "vim-mode") == 0) { - // Configure aliases for Vim-like operation - add_alias("v", "vim"); - - // Check for neovim first - FILE *test_nvim = popen("which nvim 2>/dev/null", "r"); - if (test_nvim) { - char buffer[128]; - if (fgets(buffer, sizeof(buffer), test_nvim) != NULL) { - // Neovim found, use it as preferred editor - pclose(test_nvim); - add_alias("e", "nvim"); - printf("Vim mode activated (using Neovim)\n"); - return 1; - } - pclose(test_nvim); - - // Check for regular vim - FILE *test_vim = popen("which vim 2>/dev/null", "r"); - if (test_vim) { - char buffer[128]; - if (fgets(buffer, sizeof(buffer), test_vim) != NULL) { - // Vim found - pclose(test_vim); - add_alias("e", "vim"); - printf("Vim mode activated\n"); - return 1; - } - pclose(test_vim); - } - } - - // Fallback to vi if neither vim nor neovim is found - add_alias("e", "vi"); - printf("Vim mode activated (using vi)\n"); - return 1; - } else if (strcmp(args[1], "emacs-mode") == 0) { - // Configure aliases for Emacs-like operation - FILE *test_emacs = popen("which emacs 2>/dev/null", "r"); - if (test_emacs) { - char buffer[128]; - if (fgets(buffer, sizeof(buffer), test_emacs) != NULL) { - pclose(test_emacs); - add_alias("e", "emacs -nw"); - printf("Emacs mode activated\n"); - return 1; - } - pclose(test_emacs); - } - - printf("Emacs not found. Emacs mode not activated.\n"); - return 1; - } - - // Format: alias name=command - char *equals = strchr(args[1], '='); - if (equals) { - // Split at equals sign - *equals = '\0'; - char *name = args[1]; - char *command = equals + 1; - - // Remove quotes around command if present - if (*command == '\'' || *command == '"') { - command++; - char *end = command + strlen(command) - 1; - if (*end == '\'' || *end == '"') { - *end = '\0'; - } - } - - add_alias(name, command); - printf("Alias added: %s='%s'\n", name, command); - } else if (args[2] != NULL) { - // Format: alias name command - add_alias(args[1], args[2]); - printf("Alias added: %s='%s'\n", args[1], args[2]); - } else { - // Just a name - show this specific alias - AliasEntry *alias = find_alias(args[1]); - if (alias) { - printf("alias %s='%s'\n", alias->name, alias->command); - } else { - printf("Alias '%s' not found\n", args[1]); - } - } - return 1; + } + + // Pre-defined aliases + if (strcmp(args[1], "vim-mode") == 0) { + // Configure aliases for Vim-like operation + add_alias("v", "vim"); + + // Check for neovim first + FILE *test_nvim = popen("which nvim 2>/dev/null", "r"); + if (test_nvim) { + char buffer[128]; + if (fgets(buffer, sizeof(buffer), test_nvim) != NULL) { + // Neovim found, use it as preferred editor + pclose(test_nvim); + add_alias("e", "nvim"); + printf("Vim mode activated (using Neovim)\n"); + return 1; + } + pclose(test_nvim); + + // Check for regular vim + FILE *test_vim = popen("which vim 2>/dev/null", "r"); + if (test_vim) { + char buffer[128]; + if (fgets(buffer, sizeof(buffer), test_vim) != NULL) { + // Vim found + pclose(test_vim); + add_alias("e", "vim"); + printf("Vim mode activated\n"); + return 1; + } + pclose(test_vim); + } + } + + // Fallback to vi if neither vim nor neovim is found + add_alias("e", "vi"); + printf("Vim mode activated (using vi)\n"); + return 1; + } else if (strcmp(args[1], "emacs-mode") == 0) { + // Configure aliases for Emacs-like operation + FILE *test_emacs = popen("which emacs 2>/dev/null", "r"); + if (test_emacs) { + char buffer[128]; + if (fgets(buffer, sizeof(buffer), test_emacs) != NULL) { + pclose(test_emacs); + add_alias("e", "emacs -nw"); + printf("Emacs mode activated\n"); + return 1; + } + pclose(test_emacs); + } + + printf("Emacs not found. Emacs mode not activated.\n"); + return 1; + } + + // Format: alias name=command + char *equals = strchr(args[1], '='); + if (equals) { + // Split at equals sign + *equals = '\0'; + char *name = args[1]; + char *command = equals + 1; + + // Remove quotes around command if present + if (*command == '\'' || *command == '"') { + command++; + char *end = command + strlen(command) - 1; + if (*end == '\'' || *end == '"') { + *end = '\0'; + } + } + + add_alias(name, command); + printf("Alias added: %s='%s'\n", name, command); + } else if (args[2] != NULL) { + // Format: alias name command + add_alias(args[1], args[2]); + printf("Alias added: %s='%s'\n", args[1], args[2]); + } else { + // Just a name - show this specific alias + AliasEntry *alias = find_alias(args[1]); + if (alias) { + printf("alias %s='%s'\n", alias->name, alias->command); + } else { + printf("Alias '%s' not found\n", args[1]); + } + } + + return 1; } /** * Command handler for the "unalias" command */ int lsh_unalias(char **args) { - if (args[1] == NULL) { - printf("unalias: missing argument\n"); - return 1; - } - - if (remove_alias(args[1])) { - printf("Alias '%s' removed\n", args[1]); - } else { - printf("Alias '%s' not found\n", args[1]); - } - + if (args[1] == NULL) { + printf("unalias: missing argument\n"); return 1; + } + + if (remove_alias(args[1])) { + printf("Alias '%s' removed\n", args[1]); + } else { + printf("Alias '%s' not found\n", args[1]); + } + + return 1; } /** * Command handler to show all aliases */ int lsh_aliases(char **args) { - for (int i = 0; i < alias_count; i++) { - printf("alias %s='%s'\n", aliases[i].name, aliases[i].command); - } - return 1; + for (int i = 0; i < alias_count; i++) { + printf("alias %s='%s'\n", aliases[i].name, aliases[i].command); + } + return 1; } /** * Get alias names for tab completion */ -char** get_alias_names(int *count) { - if (alias_count == 0 || !count) { - *count = 0; - return NULL; - } - - char **names = (char**)malloc(alias_count * sizeof(char*)); - if (!names) { - *count = 0; - return NULL; - } - - for (int i = 0; i < alias_count; i++) { - names[i] = strdup(aliases[i].name); - } - - *count = alias_count; - return names; +char **get_alias_names(int *count) { + if (alias_count == 0 || !count) { + *count = 0; + return NULL; + } + + char **names = (char **)malloc(alias_count * sizeof(char *)); + if (!names) { + *count = 0; + return NULL; + } + + for (int i = 0; i < alias_count; i++) { + names[i] = strdup(aliases[i].name); + } + + *count = alias_count; + return names; } /** * Expand alias in args array */ -char** expand_alias(char **args) { - if (!args || !args[0]) { - return NULL; - } - - // Check if the command is an alias - AliasEntry *alias = find_alias(args[0]); - if (!alias) { - return NULL; - } - - // Count tokens in alias command - char *alias_copy = strdup(alias->command); - if (!alias_copy) { - return NULL; - } - - char **alias_tokens = malloc(LSH_TOK_BUFSIZE * sizeof(char*)); - if (!alias_tokens) { - free(alias_copy); - return NULL; - } - - char *token, *rest = alias_copy; - int token_count = 0; - - while ((token = strtok_r(rest, " \t", &rest)) != NULL) { - alias_tokens[token_count++] = strdup(token); - - if (token_count >= LSH_TOK_BUFSIZE) { - fprintf(stderr, "lsh: alias expansion: too many tokens\n"); - break; - } - } - +char **expand_alias(char **args) { + if (!args || !args[0]) { + return NULL; + } + + // Check if the command is an alias + AliasEntry *alias = find_alias(args[0]); + if (!alias) { + return NULL; + } + + // Count tokens in alias command + char *alias_copy = strdup(alias->command); + if (!alias_copy) { + return NULL; + } + + char **alias_tokens = malloc(LSH_TOK_BUFSIZE * sizeof(char *)); + if (!alias_tokens) { free(alias_copy); - - // Count original arguments - int arg_count = 0; - while (args[arg_count] != NULL) { - arg_count++; + return NULL; + } + + char *token, *rest = alias_copy; + int token_count = 0; + + while ((token = strtok_r(rest, " \t", &rest)) != NULL) { + alias_tokens[token_count++] = strdup(token); + + if (token_count >= LSH_TOK_BUFSIZE) { + fprintf(stderr, "lsh: alias expansion: too many tokens\n"); + break; } - - // Allocate space for expanded command - char **expanded_args = malloc((token_count + arg_count) * sizeof(char*)); - if (!expanded_args) { - for (int i = 0; i < token_count; i++) { - free(alias_tokens[i]); - } - free(alias_tokens); - return NULL; - } - - // Copy alias tokens + } + + free(alias_copy); + + // Count original arguments + int arg_count = 0; + while (args[arg_count] != NULL) { + arg_count++; + } + + // Allocate space for expanded command + char **expanded_args = malloc((token_count + arg_count) * sizeof(char *)); + if (!expanded_args) { for (int i = 0; i < token_count; i++) { - expanded_args[i] = alias_tokens[i]; + free(alias_tokens[i]); } - - // Copy remaining arguments (skip the command) - for (int i = 1; i < arg_count; i++) { - expanded_args[token_count + i - 1] = strdup(args[i]); - } - - // Null-terminate the array - expanded_args[token_count + arg_count - 1] = NULL; - free(alias_tokens); - return expanded_args; -} \ No newline at end of file + return NULL; + } + + // Copy alias tokens + for (int i = 0; i < token_count; i++) { + expanded_args[i] = alias_tokens[i]; + } + + // Copy remaining arguments (skip the command) + for (int i = 1; i < arg_count; i++) { + expanded_args[token_count + i - 1] = strdup(args[i]); + } + + // Null-terminate the array + expanded_args[token_count + arg_count - 1] = NULL; + + free(alias_tokens); + return expanded_args; +}