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