Adding loading of history using readline/history.

This commit is contained in:
Martin Dvorak 2013-12-10 23:12:44 +01:00
parent f5fd8ec32b
commit 2e3556c814
4 changed files with 224 additions and 0 deletions

142
src/hstr_history.c Normal file
View file

@ -0,0 +1,142 @@
#include "include/hstr_history.h"
static int historyItemsCount;
static char** historyItems;
char* getHistoryFile() {
char *home = getenv(ENV_VAR_HOME);
char *fileName = (char*) malloc(
strlen(home) + 1 + strlen(FILE_HISTORY) + 1);
strcpy(fileName, home);
strcat(fileName, "/");
strcat(fileName, FILE_HISTORY);
return fileName;
}
#ifdef GET_HISTORY_FROM_FILE
static char *historyAsString;
char *load_history_file() {
char* fileName = getHistoryFile();
if(access(fileName, F_OK) != -1) {
char *file_contents;
long input_file_size;
FILE *input_file = fopen(fileName, "rb");
fseek(input_file, 0, SEEK_END);
input_file_size = ftell(input_file);
rewind(input_file);
file_contents = malloc((input_file_size + 1) * (sizeof(char)));
if(fread(file_contents, sizeof(char), input_file_size, input_file)==-1) {
exit(EXIT_FAILURE);
}
fclose(input_file);
file_contents[input_file_size] = 0;
return file_contents;
} else {
fprintf(stderr,"\nHistory file not found: %s\n",fileName);
exit(EXIT_FAILURE);
}
}
int count_history_lines(char *history) {
int i = 0;
char *p=strchr(history,'\n');
while (p!=NULL) {
i++;
p=strchr(p+1,'\n');
}
return i;
}
char **get_tokenized_history(char *history, int lines) {
char **tokens = malloc(sizeof(char*) * lines);
int i = 0;
char *pb=history, *pe;
pe=strchr(history, '\n');
while(pe!=NULL) {
tokens[i]=pb;
*pe=0;
pb=pe+1;
pe=strchr(pb, '\n');
i++;
}
return tokens;
}
char** get_history_items() {
historyAsString = load_history_file(FILE_HISTORY);
historyItemsCount = count_history_lines(historyAsString);
historyItems = get_tokenized_history(historyAsString, historyItemsCount);
reverse_char_pointer_array(historyItems, historyItemsCount);
return historyItems;
}
int get_history_items_size() {
return historyItemsCount;
}
void free_history_items() {
free(historyAsString);
free(historyItems);
}
#else
char** get_history_items() {
using_history();
char *historyFile = getenv(ENV_VAR_HISTFILE);
if(historyFile==NULL || strlen(historyFile)==0) {
historyFile=getHistoryFile();
}
if(read_history(historyFile)!=0) {
fprintf(stderr, "\nUnable to read history file from '%s'!\n",historyFile);
exit(EXIT_FAILURE);
}
HISTORY_STATE *historyState=history_get_history_state();
if(historyState->length > 0) {
historyItemsCount=historyState->length;
historyItems=(char**)malloc(historyItemsCount*sizeof(char*));
HIST_ENTRY **historyList=history_list();
int i;
char *entry, *item;
for(i=0; i<historyItemsCount; i++) {
entry=historyList[i]->line;
if(entry!=NULL) {
item=malloc(strlen(entry)+1);
strcpy(item, entry);
}
}
} else {
historyItemsCount=0;
historyItems=NULL;
}
return historyItems;
}
int get_history_items_size() {
return historyItemsCount;
}
void free_history_items() {
free(historyItems);
}
#endif

36
src/hstr_utils.c Normal file
View file

@ -0,0 +1,36 @@
#include "include/hstr_utils.h"
#define DEFAULT_COMMAND "pwd"
void tiocsti() {
char buf[] = DEFAULT_COMMAND;
int i;
for (i = 0; i < sizeof buf - 1; i++) {
ioctl(0, TIOCSTI, &buf[i]);
}
}
void fill_terminal_input(char* cmd){
size_t size = strlen(cmd);
int i;
char *c;
for (i = 0; i < size; i++) {
// terminal I/O control, simulate terminal input
c=(cmd+i);
ioctl(0, TIOCSTI, c);
}
printf("\n");
}
void reverse_char_pointer_array(char **array, int length) {
int i;
char * temp;
for (i=0; i<length/2; i++) {
temp = array[i];
array[i] = array[length-i-1];
array[length-i-1] = temp;
}
}

View file

@ -0,0 +1,25 @@
#ifndef _HSTR_HISTORY_H_
#define _HSTR_HISTORY_H_
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <readline/history.h>
#include <unistd.h>
#include "hstr_utils.h"
#define GET_HISTORY_FROM_FILE
//#define GET_HISTORY_USING_LIBRARY
#define ENV_VAR_USER "USER"
#define ENV_VAR_HOME "HOME"
#define ENV_VAR_HISTFILE "HISTFILE"
#define FILE_HISTORY ".bash_history"
char** get_history_items();
int get_history_items_size();
void free_history_items();
#endif

21
src/include/hstr_utils.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef _HSTR_UTILS_H
#define _HSTR_UTILS_H
#include <sys/ioctl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
void tiocsti();
void fill_terminal_input(char* cmd);
void reverse_char_pointer_array(char **array, int length);
#ifdef __cplusplus
}
#endif
#endif