/****** console.c All functions pertaining to the console are defined here. ******/ #include "console.h" #include #include #include "main.h" // shouldn't be here /**** consoleLog This function takes the passed \0 terminated string, creates a new ConsoleEntry and updates the console log chain accordingly. Generally called to do error logging, connection/function information, basic informational messages, etc.. Arguments: const char *string Returns: void ****/ void consoleLog(const char *string) { struct ConsoleEntry *new_entry; new_entry = malloc(sizeof(struct ConsoleEntry)); int bytes = strlen(string)+1; new_entry->string = malloc(bytes); new_entry->size = bytes; memcpy(new_entry->string, string, bytes); if (console_last_entry) { console_last_entry->next = new_entry; new_entry->prev = console_last_entry; new_entry->next = NULL; } else { console_first_entry = new_entry; new_entry->next = NULL; new_entry->prev = NULL; } console_last_entry = new_entry; } /**** consoleGetEntryString Returns the string property of the ConsoleEntry pointed to by the passed pointer. Arguments: const struct ConsoleEntry *entry Returns: const char* ****/ const char *consoleGetEntryString(const struct ConsoleEntry *entry) { if (entry->string) { return entry->string; } return ""; } /**** consoleGenerateHash Generates a numerical hash for the passed string. This string is generated by combining the numerical value of all the chars and running modulo of COMMAND_HASH_SIZE on it. This works, but should be improved later to reduce chances of conflicting numerical hashes. Generally called through consoleAddCommand. Arguments: const char *string Returns: int ****/ int consoleGenerateHash(const char* string) { int i, sum; size_t string_length = strlen(string); for (sum=0, i=0; i < string_length; i++) { sum += string[i]; } return sum % COMMAND_HASH_SIZE; } /**** consoleAddCommand Takes command_string, generates a new hash via consoleGenerateHash, and adds the passed function pointer to the console_commands_table with the new hash. Arguments: const char *string Globals Modified: console_commands_table Returns: void ****/ void consoleAddCommand(const char *command_string, void(*function)) { int string_hash = consoleGenerateHash(command_string); consoleLog("command added!"); // TODO: consoleLogF(formatted log) console_commands_table[string_hash] = function; } /**** consoleGetCommand This semi-convoluted function takes a full command string, such as "set_video 1024x768 1", and creates a new malloc'd array of strings. The first member of the array is the actual command, i.e., "set_video", and the second is the remainder of the string. This allows for consoleProcessCommand to get the hash of command_array[0] and call the command in console_commands_table with command_array[1] as the argument. NOTE: consoleFreeCommand MUST be called, otherwise memory will be lost. Arguments: const char *string Returns: char** ****/ char **consoleGetCommand(const char *string) { int i = 0; char** command_array; command_array = malloc(2 * sizeof(char*)); while(string[i] != ' ' && string[i] != '\0') { i++; } command_array[0] = malloc(i+1); // our command command_array[1] = malloc(console_cmd_size-i+1); // our argument string memcpy(command_array[0], string, i); memcpy(command_array[1], string+i+1, console_cmd_size-i); command_array[0][i] = '\0'; command_array[1][console_cmd_size-i] = '\0'; return command_array; } /**** consoleFreeCommand frees the memory allocated by consoleGetCommand Arguments: char **command_array ****/ void consoleFreeCommand(char **command_array) { free(command_array[0]); free(command_array[1]); free(command_array); } /**** consoleProcessCommand Takes a full command string, such as "set_video 1024x768 1" and attempts to call the corresponding function in console_commands_table, passing the non-command portion of the string to it. This is generally called from within the consoleContext once the user has pressed return. Arguments: const char *command_string Returns: void ****/ void consoleProcessCommand(const char *command_string) { char **command = consoleGetCommand(command_string); int command_hash = consoleGenerateHash(command[0]); if (console_commands_table[command_hash]) { (*console_commands_table[command_hash])(command[1]); } else { consoleLog("Command not found!"); } consoleFreeCommand(command); }