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