a34490a8ef790b95429ac28ccc68cac1e51954c5
[yaz-moved-to-github.git] / client / fhistory.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2011 Index Data
3  * See the file LICENSE for details.
4  */
5 /** \file fhistory.c
6  *  \brief file history implementation
7  */
8 #if HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <assert.h>
16 #include <time.h>
17 #include <ctype.h>
18 #if HAVE_SYS_TYPES_H
19 #include <sys/types.h>
20 #endif
21
22 #include "fhistory.h"
23
24
25 struct file_history {
26     WRBUF wr;
27 };
28
29 file_history_t file_history_new()
30 {
31     file_history_t fh = (file_history_t) xmalloc(sizeof(*fh));
32     fh->wr = wrbuf_alloc();
33     return fh;
34 }
35
36 void file_history_destroy(file_history_t *fhp)
37 {
38     if (*fhp)
39     {
40         wrbuf_destroy((*fhp)->wr);
41         xfree(*fhp);
42         *fhp = 0;
43     }
44 }
45
46 void file_history_add_line(file_history_t fh, const char *line)
47 {
48     wrbuf_puts(fh->wr, line);
49     wrbuf_puts(fh->wr, "\n");
50 }
51
52 int file_history_load(file_history_t fh)
53 {
54     FILE *f;
55     char* homedir = getenv("HOME");
56     char fname[1024];
57     int ret = 0;
58
59     wrbuf_rewind(fh->wr);
60     sprintf(fname, "%.500s%s%s", homedir ? homedir : "",
61             homedir ? "/" : "", ".yazclient.history");
62
63     f = fopen(fname, "r");
64     if (f)
65     {
66         int c;
67         while ((c = fgetc(f)) != EOF)
68             wrbuf_putc(fh->wr, c);
69         fclose(f);
70     }
71     return ret;
72 }
73
74 #define FILE_SAVE_HISTORY_MAX 16384
75
76 int file_history_save(file_history_t fh)
77 {
78     FILE *f;
79     char* homedir = getenv("HOME");
80     char fname[1024];
81     int ret = 0;
82     size_t sz = wrbuf_len(fh->wr);
83
84     if (!sz)
85         return 0;
86     sprintf(fname, "%.500s%s%s", homedir ? homedir : "",
87             homedir ? "/" : "", ".yazclient.history");
88
89     f = fopen(fname, "w");
90     if (!f)
91     {
92         ret = -1;
93     }
94     else
95     {
96         size_t w;
97         const char *start = wrbuf_buf(fh->wr);
98         if (sz > FILE_SAVE_HISTORY_MAX)
99         {
100             const char *nl = strchr(
101                 wrbuf_buf(fh->wr) + sz - FILE_SAVE_HISTORY_MAX,
102                 '\n');
103             if (nl)
104             {
105                 nl++;
106                 sz = sz - (nl - start);
107                 start = nl;
108             }
109         }
110         w = fwrite(start, 1, sz, f);
111         if (w != sz)
112             ret = -1;
113         if (fclose(f))
114             ret = -1;
115     }
116     return ret;
117 }
118
119 int file_history_trav(file_history_t fh, void *client_data,
120                       void (*callback)(void *client_data, const char *line))
121 {
122     size_t off = 0;
123
124     while (off < wrbuf_len(fh->wr))
125     {
126         size_t i;
127         for (i = off; i < wrbuf_len(fh->wr); i++)
128         {
129             if (wrbuf_buf(fh->wr)[i] == '\n')
130             {
131                 wrbuf_buf(fh->wr)[i] = '\0';
132                 callback(client_data, wrbuf_cstr(fh->wr) + off);
133                 wrbuf_buf(fh->wr)[i] = '\n';
134                 i++;
135                 break;
136             }
137         }
138         off = i;
139     }
140     return 0;
141 }
142
143 /*
144  * Local variables:
145  * c-basic-offset: 4
146  * c-file-style: "Stroustrup"
147  * indent-tabs-mode: nil
148  * End:
149  * vim: shiftwidth=4 tabstop=8 expandtab
150  */
151