139 lines
3.5 KiB
C
Executable File
139 lines
3.5 KiB
C
Executable File
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <string.h>
|
|
|
|
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);
|
|
}
|