-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhistory.c
96 lines (80 loc) · 2.47 KB
/
history.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
Filename: history.c
Author: Christopher Sasarak <[email protected]>
This file includes code for storing, maintaining, and retrieving
the shell's history.
*/
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include "config.h"
static char** history = NULL;
static int oldest_cmd = 0; // The oldest command in history
/* Add a new command string to the history, deleting
one in the process if that would make more than HIST_SIZE
commands in history. Return 0 on success, set errno and return -1 otherwise
*/
int add_cmd(char *cmd){
static int last_cmd = 0; // The most recently added command
if(history != NULL){
// Check if we need to wrap around
if(last_cmd == HIST_SIZE - 1)
last_cmd = 0;
else
last_cmd++;
if(history[last_cmd] != NULL){
free(history[last_cmd]);
oldest_cmd = (oldest_cmd < HIST_SIZE - 1) ? oldest_cmd + 1 : 0;
}
}
else{ // Allocate memory for the history if it isn't there
history = (char**)calloc(HIST_SIZE, sizeof(char*));
oldest_cmd = last_cmd;
}
history[last_cmd] = (char*)malloc(strlen(cmd));
// Check for memory allocation errors
if(history[last_cmd] == NULL){
return -1;
}
strcpy(history[last_cmd], cmd);
return 0;
}
/* This function can be used to iterate through the history from the oldest to
the most recent command It returns a pointer to the next string in the
history, or NULL if it has reached the end or there is no history. Passing
0 in as the parameter will get the next value, while anything else will
cause iteration to restart from the beginning and return the first history
item.
*/
char* next_cmd(int reset){
static int curr_cmd = 0;
// Return if there isn't a history yet
if(history == NULL)
return NULL;
// Reset the iteration if necessary
if(reset){
curr_cmd = oldest_cmd;
return history[curr_cmd];
}
curr_cmd++;
if(curr_cmd == HIST_SIZE){
curr_cmd = 0;
}
if(curr_cmd == oldest_cmd){
return (char*) NULL;
}
return history[curr_cmd];
}
void print_history(){
// Reset the iteration and get the first history element
char* cmd = next_cmd(1);
// Return if there isn't a history yet
if(cmd == NULL)
return;
printf("%s\n", cmd);
// Print the rest
while((cmd = next_cmd(0)) != NULL){
printf("%s\n", cmd);
}
}