261 lines
6.3 KiB
C++
261 lines
6.3 KiB
C++
|
/* c_history.cpp
|
||
|
*
|
||
|
* Copyright (c) 1994-1996, Marko Macek
|
||
|
*
|
||
|
* You may distribute under the terms of either the GNU General Public
|
||
|
* License or the Artistic License, as specified in the README file.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "fte.h"
|
||
|
|
||
|
#ifdef CONFIG_HISTORY
|
||
|
|
||
|
#define HISTORY_VER "FTE History 1\n"
|
||
|
|
||
|
char HistoryFileName[256] = "";
|
||
|
|
||
|
static FPosHistory **FPHistory = 0;
|
||
|
static int FPHistoryCount = 0;
|
||
|
|
||
|
static InputHistory inputHistory = { 0, 0, 0 };
|
||
|
|
||
|
void ClearHistory() { /*FOLD00*/
|
||
|
|
||
|
// free filenames from all entries
|
||
|
while(FPHistoryCount--)
|
||
|
{
|
||
|
free(FPHistory[FPHistoryCount]->FileName);
|
||
|
free(FPHistory[FPHistoryCount]);
|
||
|
}
|
||
|
|
||
|
// free history list
|
||
|
free(FPHistory);
|
||
|
|
||
|
// free input history
|
||
|
{
|
||
|
while(inputHistory.Count--)
|
||
|
{
|
||
|
free(inputHistory.Line[inputHistory.Count]);
|
||
|
}
|
||
|
free(inputHistory.Line);
|
||
|
free(inputHistory.Id);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int SaveHistory(char *FileName) { /*FOLD00*/
|
||
|
FILE *fp;
|
||
|
|
||
|
fp = fopen(FileName, "w");
|
||
|
if (fp == 0)
|
||
|
return 0;
|
||
|
setvbuf(fp, FileBuffer, _IOFBF, sizeof(FileBuffer));
|
||
|
fprintf(fp, HISTORY_VER);
|
||
|
if (FPHistory) { // file position history
|
||
|
int i;
|
||
|
for (i = 0; i < FPHistoryCount; i++)
|
||
|
fprintf(fp, "F|%d|%d|%s\n",
|
||
|
FPHistory[i]->Row,
|
||
|
FPHistory[i]->Col,
|
||
|
FPHistory[i]->FileName);
|
||
|
}
|
||
|
{ // input history
|
||
|
for (int i = 0; i < inputHistory.Count; i++) {
|
||
|
fprintf(fp, "I|%d|%s\n", inputHistory.Id[i], inputHistory.Line[i]);
|
||
|
}
|
||
|
}
|
||
|
fclose(fp);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int LoadHistory(char *FileName) { /*fold00*/
|
||
|
FILE *fp;
|
||
|
char line[2048];
|
||
|
char *p, *e;
|
||
|
|
||
|
fp = fopen(FileName, "r");
|
||
|
if (fp == 0)
|
||
|
return 0;
|
||
|
|
||
|
setvbuf(fp, FileBuffer, _IOFBF, sizeof(FileBuffer));
|
||
|
|
||
|
if (fgets(line, sizeof(line), fp) == 0 ||
|
||
|
strcmp(line, HISTORY_VER) != 0)
|
||
|
{
|
||
|
fclose(fp);
|
||
|
return 0;
|
||
|
}
|
||
|
while (fgets(line, sizeof(line), fp) != 0) {
|
||
|
if (line[0] == 'F' && line[1] == '|') { // input history
|
||
|
int r, c;
|
||
|
p = line + 2;
|
||
|
r = strtol(p, &e, 10);
|
||
|
if (e == p)
|
||
|
break;
|
||
|
if (*e == '|')
|
||
|
e++;
|
||
|
else
|
||
|
break;
|
||
|
c = strtol(p = e, &e, 10);
|
||
|
if (e == p)
|
||
|
break;
|
||
|
if (*e == '|')
|
||
|
e++;
|
||
|
else
|
||
|
break;
|
||
|
e = strchr(p = e, '\n');
|
||
|
if (e == 0)
|
||
|
break;
|
||
|
*e = 0;
|
||
|
if (UpdateFPos(p, r, c) == 0)
|
||
|
break;
|
||
|
} else if (line[0] == 'I' && line[1] == '|') { // file position history
|
||
|
int i;
|
||
|
|
||
|
p = line + 2;
|
||
|
i = strtol(p, &e, 10);
|
||
|
if (e == p)
|
||
|
break;
|
||
|
if (*e == '|')
|
||
|
e++;
|
||
|
else
|
||
|
break;
|
||
|
e = strchr(p = e, '\n');
|
||
|
if (e == 0)
|
||
|
break;
|
||
|
*e = 0;
|
||
|
AddInputHistory(i, p);
|
||
|
}
|
||
|
}
|
||
|
fclose(fp);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int UpdateFPos(char *FileName, int Row, int Col) { /*fold00*/
|
||
|
int L = 0, R = FPHistoryCount, M, N;
|
||
|
FPosHistory *fp, **NH;
|
||
|
int cmp;
|
||
|
|
||
|
if (FPHistory != 0) {
|
||
|
while (L < R) {
|
||
|
M = (L + R) / 2;
|
||
|
cmp = filecmp(FileName, FPHistory[M]->FileName);
|
||
|
if (cmp == 0) {
|
||
|
FPHistory[M]->Row = Row;
|
||
|
FPHistory[M]->Col = Col;
|
||
|
return 1;
|
||
|
} else if (cmp < 0) {
|
||
|
R = M;
|
||
|
} else {
|
||
|
L = M + 1;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
FPHistoryCount = 0;
|
||
|
L = 0;
|
||
|
}
|
||
|
assert(L >= 0 && L <= FPHistoryCount);
|
||
|
fp = (FPosHistory *)malloc(sizeof(FPosHistory));
|
||
|
if (fp == 0)
|
||
|
return 0;
|
||
|
fp->Row = Row;
|
||
|
fp->Col = Col;
|
||
|
fp->FileName = strdup(FileName);
|
||
|
if (fp->FileName == 0) {
|
||
|
free(fp);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
N = 64;
|
||
|
while (N <= FPHistoryCount) N *= 2;
|
||
|
NH = (FPosHistory **)realloc((void *)FPHistory, N * sizeof(FPosHistory *));
|
||
|
if (NH == 0)
|
||
|
{
|
||
|
free(fp->FileName);
|
||
|
free(fp);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
FPHistory = NH;
|
||
|
|
||
|
if (L < FPHistoryCount)
|
||
|
memmove(FPHistory + L + 1,
|
||
|
FPHistory + L,
|
||
|
(FPHistoryCount - L) * sizeof(FPosHistory *));
|
||
|
FPHistory[L] = fp;
|
||
|
FPHistoryCount++;
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int RetrieveFPos(char *FileName, int &Row, int &Col) { /*FOLD00*/
|
||
|
int L = 0, R = FPHistoryCount, M;
|
||
|
int cmp;
|
||
|
|
||
|
if (FPHistory == 0)
|
||
|
return 0;
|
||
|
|
||
|
while (L < R) {
|
||
|
M = (L + R) / 2;
|
||
|
cmp = filecmp(FileName, FPHistory[M]->FileName);
|
||
|
if (cmp == 0) {
|
||
|
Row = FPHistory[M]->Row;
|
||
|
Col = FPHistory[M]->Col;
|
||
|
return 1;
|
||
|
} else if (cmp < 0) {
|
||
|
R = M;
|
||
|
} else {
|
||
|
L = M + 1;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int AddInputHistory(int Id, char *String) { /*fold00*/
|
||
|
if (inputHistory.Count < MAX_INPUT_HIST) {
|
||
|
inputHistory.Count++;
|
||
|
inputHistory.Line = (char **) realloc((void *) inputHistory.Line,
|
||
|
inputHistory.Count * sizeof(char *));
|
||
|
inputHistory.Id = (int *) realloc((void *) inputHistory.Id,
|
||
|
inputHistory.Count * sizeof(int *));
|
||
|
} else {
|
||
|
free(inputHistory.Line[inputHistory.Count - 1]);
|
||
|
}
|
||
|
memmove(inputHistory.Line + 1,
|
||
|
inputHistory.Line,
|
||
|
(inputHistory.Count - 1) * sizeof(char *));
|
||
|
memmove(inputHistory.Id + 1,
|
||
|
inputHistory.Id,
|
||
|
(inputHistory.Count - 1) * sizeof(int *));
|
||
|
inputHistory.Id[0] = Id;
|
||
|
inputHistory.Line[0] = strdup(String);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int CountInputHistory(int Id) { /*fold00*/
|
||
|
int i, c = 0;
|
||
|
|
||
|
for (i = 0; i < inputHistory.Count; i++)
|
||
|
if (inputHistory.Id[i] == Id) c++;
|
||
|
return c;
|
||
|
}
|
||
|
|
||
|
int GetInputHistory(int Id, char *String, int len, int Nth) { /*fold00*/
|
||
|
int i = 0;
|
||
|
|
||
|
assert(len > 0);
|
||
|
|
||
|
while (i < inputHistory.Count) {
|
||
|
if (inputHistory.Id[i] == Id) {
|
||
|
Nth--;
|
||
|
if (Nth == 0) {
|
||
|
strncpy(String, inputHistory.Line[i], len);
|
||
|
String[len - 1] = 0;
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
i++;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|