blob: f2a4b9176feda543d88c8c94559cbcfe089d804a [file] [log] [blame]
#include <stdlib.h> /* for malloc */
#include <stdio.h>
#include <strings.h>
#include <wchar.h>
#include "wc_history.h"
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#include <R_ext/Error.h>
static int HIST_SIZE = 512;
static int hist_pos = 0, hist_last = 0, gl_beep_on = 1;
static wchar_t **hist_buf;
static int wgl_init_done = -1;
static void gl_error(char *msg)
{
char buf[1001];
wgl_init_done = 1;
snprintf(buf, 1000,
"%s\nDisabling commands history for this session", msg);
buf[1000] = '\0';
R_ShowMessage(buf);
}
static void gl_beep(void)
{
if(gl_beep_on) MessageBeep(MB_OK);
}
static wchar_t *hist_save(const wchar_t *p)
/* makes a copy of the string */
{
wchar_t *s = 0;
int len = wcslen(p);
wchar_t *nl = wcschr(p, L'\n');
if (nl) {
if ((s = (wchar_t *) malloc(len * sizeof(wchar_t)))) {
wcsncpy(s, p, len-1);
s[len-1] = 0;
}
} else {
if ((s = (wchar_t *) malloc((len+1) * sizeof(wchar_t))))
wcscpy(s, p);
}
if (s == 0)
gl_error("*** Error: hist_save() failed on malloc");
return s;
}
void wgl_hist_init(int size, int beep)
{
int i;
HIST_SIZE = size;
hist_buf = (wchar_t **) malloc(size * sizeof(wchar_t *));
if(!hist_buf) {
gl_error("\n*** Error: wgl_hist_init() failed on malloc\n");
return;
}
hist_buf[0] = L"";
for (i = 1; i < HIST_SIZE; i++)
hist_buf[i] = (wchar_t *)0;
hist_pos = hist_last = 0;
wgl_init_done = 0;
gl_beep_on = beep;
}
void wgl_histadd(const wchar_t *buf)
{
const wchar_t *p = buf;
if(wgl_init_done > 0) return;
while (*p == ' ' || *p == '\t' || *p == '\n') p++;
if (*p) {
hist_buf[hist_last] = hist_save(buf);
hist_last = hist_last + 1;
if(hist_last > HIST_SIZE - 1) {
int i, size = HIST_SIZE + 512;
hist_buf = (wchar_t **)
realloc(hist_buf, size * sizeof(wchar_t *));
if(!hist_buf) {
gl_error("*** Error: wgl_histadd() failed on realloc");
return;
}
for(i = HIST_SIZE; i < size; i++)
hist_buf[i] = (wchar_t *)0;
HIST_SIZE = size;
}
hist_buf[hist_last] = L"";
}
hist_pos = hist_last;
}
wchar_t *wgl_hist_prev(void)
/* loads previous hist entry into input buffer, sticks on first */
{
wchar_t *p = 0;
int next = hist_pos - 1;
if(wgl_init_done) return L"";
if (hist_buf[hist_pos] != 0 && next >= 0) {
hist_pos = next;
p = hist_buf[hist_pos];
}
if (p == 0) {
p = L"";
gl_beep();
}
return p;
}
wchar_t *wgl_hist_next(void)
/* loads next hist entry into input buffer, clears on last */
{
wchar_t *p = 0;
if(wgl_init_done) return L"";
if (hist_pos != hist_last) {
hist_pos = hist_pos+1;
p = hist_buf[hist_pos];
}
if (p == 0) {
p = L"";
gl_beep();
}
return p;
}
void wgl_savehistory(const char *file, int size)
{
FILE *fp;
int i, init;
if (wgl_init_done || !file || !hist_last) return;
fp = fopen(file, "w");
if (!fp) {
char msg[256];
snprintf(msg, 256, "Unable to open %s", file);
R_ShowMessage(msg);
return;
}
init = hist_last - size;
init = (init < 0) ? 0 : init;
for (i = init; i < hist_last; i++)
fprintf(fp, "%ls\n", hist_buf[i]);
fclose(fp);
}
void wgl_loadhistory(const char *file)
{
FILE *fp;
int i;
wchar_t buf[1000];
if (wgl_init_done || !file) return;
fp = fopen(file, "r");
if (!fp) return;
for(i = 0;; i++) {
if(!fgetws(buf, 1000, fp)) break;
wgl_histadd(buf);
}
fclose(fp);
}
void wgl_savehistoryW(const wchar_t *file, int size)
{
FILE *fp;
int i, init;
if (wgl_init_done || !file || !hist_last) return;
fp = _wfopen(file, L"w");
if (!fp) {
char msg[256];
snprintf(msg, 256, "Unable to open %ls", file);
R_ShowMessage(msg);
return;
}
init = hist_last - size;
init = (init < 0) ? 0 : init;
for (i = init; i < hist_last; i++)
fprintf(fp, "%ls\n", hist_buf[i]);
fclose(fp);
}
void wgl_loadhistoryW(const wchar_t *file)
{
FILE *fp;
int i;
wchar_t buf[1000];
if (wgl_init_done || !file) return;
fp = _wfopen(file, L"r");
if (!fp) return;
for(i = 0;; i++) {
if(!fgetws(buf, 1000, fp)) break;
wgl_histadd(buf);
}
fclose(fp);
}