#include #include #include #include typedef struct MemoHistory{ int lineNumber; char command[100]; }MemoHistory; void AddHistoryData(char command[100]); bool CheckArgumentSet(int argc, char* argv[], char argumentLetter); void GetCommandNumber(MemoHistory* historyData, int commandNumber); int GetHistoryLineCount(); void Memo(int argc, char* argv[]); FILE* OpenHistoryFile(char* openType); void PrintHistory(); void RunCommandNumber(char* command); void TestHistoryData(); int main(int argc, char* argv[]) { if (argc == 1) PrintHistory(); if (argc > 1) Memo(argc, argv); return 0; } void AddHistoryData(char command[100]) { FILE* historyFile = OpenHistoryFile("a"); MemoHistory historyData; strcpy(historyData.command, command); historyData.lineNumber = GetHistoryLineCount() + 1; fwrite(&historyData, sizeof(MemoHistory), 1, historyFile); return; } // Check if an argument is set // Returns true if found, false if argument not found bool CheckArgumentSet(int argc, char* argv[], char argumentLetter) { char argumentHyphen = '-'; for (int i = 1; i < argc; i++) if ((*(argv[i]) == argumentHyphen) && (*(argv[i]+1) == argumentLetter)) return 1; return 0; } // Get numbered command from memo.history void GetCommandNumber(MemoHistory* historyData, int commandNumber) { FILE* historyFile = OpenHistoryFile("r"); while(fread(historyData, sizeof(MemoHistory), 1, historyFile)) if (historyData->lineNumber == commandNumber) break; fclose(historyFile); return; } // Get the highest line number in the history file and returns it int GetHistoryLineCount() { FILE* historyFile = OpenHistoryFile("r"); MemoHistory historyData; historyData.lineNumber = 0; while(fread(&historyData, sizeof(MemoHistory), 1, historyFile)) ; fclose(historyFile); return historyData.lineNumber; } // Base Memo function // Runs command then puts command in memo.history void Memo(int argc, char* argv[]) { if (CheckArgumentSet(argc, argv, 'e')) { RunCommandNumber(argv[2]); return; } char commandInput[100]; for (int i = 1; i < argc; i++) { strcat(commandInput, argv[i]); strcat(commandInput, " "); } system(commandInput); AddHistoryData(commandInput); } // Safely opens memo.history // Returns true if successful, false if unsuccessful FILE* OpenHistoryFile(char* openType) { FILE* historyFile; if ((historyFile = fopen("memo.history", openType)) == NULL) { perror("memo.history"); exit(EXIT_FAILURE); } return historyFile; } // Prints data from memo.history file void PrintHistory() { FILE* historyFile = OpenHistoryFile("r"); MemoHistory historyData; while(fread(&historyData, sizeof(MemoHistory), 1, historyFile)) printf("%2d %s\n", historyData.lineNumber, historyData.command); fclose(historyFile); } // Run numbered command from memo.history void RunCommandNumber(char* command) { MemoHistory historyData; int commandNumber = 0; sscanf(command, "%d", &commandNumber); GetCommandNumber(&historyData, commandNumber); system(historyData.command); } void TestHistoryData() { MemoHistory historyData; FILE* historyFile = OpenHistoryFile("w"); for (int i = 1; i < 11; i++) { historyData.lineNumber = i; strcpy(historyData.command, "echo hello world"); fwrite(&historyData, sizeof(MemoHistory), 1, historyFile); } fclose(historyFile); }