Intial commit
[profile/ivi/w3m.git] / history.c
1 /* $Id: history.c,v 1.11 2003/09/26 17:59:51 ukai Exp $ */
2 #include "fm.h"
3
4 #ifdef USE_HISTORY
5 Buffer *
6 historyBuffer(Hist *hist)
7 {
8     Str src = Strnew();
9     HistItem *item;
10     char *p, *q;
11
12     /* FIXME: gettextize? */
13     Strcat_charp(src, "<html>\n<head><title>History Page</title></head>\n");
14     Strcat_charp(src, "<body>\n<h1>History Page</h1>\n<hr>\n");
15     Strcat_charp(src, "<ol>\n");
16     if (hist && hist->list) {
17         for (item = hist->list->last; item; item = item->prev) {
18             q = html_quote((char *)item->ptr);
19             if (DecodeURL)
20                 p = html_quote(url_unquote_conv((char *)item->ptr, 0));
21             else
22                 p = q;
23             Strcat_charp(src, "<li><a href=\"");
24             Strcat_charp(src, q);
25             Strcat_charp(src, "\">");
26             Strcat_charp(src, p);
27             Strcat_charp(src, "</a>\n");
28         }
29     }
30     Strcat_charp(src, "</ol>\n</body>\n</html>");
31     return loadHTMLString(src);
32 }
33
34 void
35 loadHistory(Hist *hist)
36 {
37     FILE *f;
38     Str line;
39
40     if (hist == NULL)
41         return;
42     if ((f = fopen(rcFile(HISTORY_FILE), "rt")) == NULL)
43         return;
44
45     while (!feof(f)) {
46         line = Strfgets(f);
47         Strchop(line);
48         Strremovefirstspaces(line);
49         Strremovetrailingspaces(line);
50         if (line->length == 0)
51             continue;
52         pushHist(hist, url_quote(line->ptr));
53     }
54     fclose(f);
55 }
56
57 void
58 saveHistory(Hist *hist, size_t size)
59 {
60     FILE *f;
61     HistItem *item;
62     char *tmpf;
63
64     if (hist == NULL || hist->list == NULL)
65         return;
66     tmpf = tmpfname(TMPF_DFL, NULL)->ptr;
67     if ((f = fopen(tmpf, "w")) == NULL) {
68         /* FIXME: gettextize? */
69         disp_err_message("Can't open history", FALSE);
70         return;
71     }
72     for (item = hist->list->first; item && hist->list->nitem > size;
73          item = item->next)
74         size++;
75     for (; item; item = item->next)
76         fprintf(f, "%s\n", (char *)item->ptr);
77     if (fclose(f) == EOF) {
78         /* FIXME: gettextize? */
79         disp_err_message("Can't save history", FALSE);
80         return;
81     }
82     rename(tmpf, rcFile(HISTORY_FILE));
83 }
84 #endif                          /* USE_HISTORY */
85
86 Hist *
87 newHist()
88 {
89     Hist *hist;
90
91     hist = New(Hist);
92     hist->list = (HistList *)newGeneralList();
93     hist->current = NULL;
94     hist->hash = NULL;
95     return hist;
96 }
97
98 Hist *
99 copyHist(Hist *hist)
100 {
101     Hist *new;
102     HistItem *item;
103
104     if (hist == NULL)
105         return NULL;
106     new = newHist();
107     for (item = hist->list->first; item; item = item->next)
108         pushHist(new, (char *)item->ptr);
109     return new;
110 }
111
112 HistItem *
113 unshiftHist(Hist *hist, char *ptr)
114 {
115     HistItem *item;
116
117     if (hist == NULL || hist->list == NULL)
118         return NULL;
119     item = (HistItem *)newListItem((void *)allocStr(ptr, -1),
120                                    (ListItem *)hist->list->first, NULL);
121     if (hist->list->first)
122         hist->list->first->prev = item;
123     else
124         hist->list->last = item;
125     hist->list->first = item;
126     hist->list->nitem++;
127     return item;
128 }
129
130 HistItem *
131 pushHist(Hist *hist, char *ptr)
132 {
133     HistItem *item;
134
135     if (hist == NULL || hist->list == NULL)
136         return NULL;
137     item = (HistItem *)newListItem((void *)allocStr(ptr, -1),
138                                    NULL, (ListItem *)hist->list->last);
139     if (hist->list->last)
140         hist->list->last->next = item;
141     else
142         hist->list->first = item;
143     hist->list->last = item;
144     hist->list->nitem++;
145     return item;
146 }
147
148 /* Don't mix pushHashHist() and pushHist()/unshiftHist(). */
149
150 HistItem *
151 pushHashHist(Hist *hist, char *ptr)
152 {
153     HistItem *item;
154
155     if (hist == NULL || hist->list == NULL)
156         return NULL;
157     item = getHashHist(hist, ptr);
158     if (item) {
159         if (item->next)
160             item->next->prev = item->prev;
161         else                    /* item == hist->list->last */
162             hist->list->last = item->prev;
163         if (item->prev)
164             item->prev->next = item->next;
165         else                    /* item == hist->list->first */
166             hist->list->first = item->next;
167         hist->list->nitem--;
168     }
169     item = pushHist(hist, ptr);
170     putHash_sv(hist->hash, ptr, (void *)item);
171     return item;
172 }
173
174 HistItem *
175 getHashHist(Hist *hist, char *ptr)
176 {
177     HistItem *item;
178
179     if (hist == NULL || hist->list == NULL)
180         return NULL;
181     if (hist->hash == NULL) {
182         hist->hash = newHash_sv(HIST_HASH_SIZE);
183         for (item = hist->list->first; item; item = item->next)
184             putHash_sv(hist->hash, (char *)item->ptr, (void *)item);
185     }
186     return (HistItem *)getHash_sv(hist->hash, ptr, NULL);
187 }
188
189 char *
190 lastHist(Hist *hist)
191 {
192     if (hist == NULL || hist->list == NULL)
193         return NULL;
194     if (hist->list->last) {
195         hist->current = hist->list->last;
196         return (char *)hist->current->ptr;
197     }
198     return NULL;
199 }
200
201 char *
202 nextHist(Hist *hist)
203 {
204     if (hist == NULL || hist->list == NULL)
205         return NULL;
206     if (hist->current && hist->current->next) {
207         hist->current = hist->current->next;
208         return (char *)hist->current->ptr;
209     }
210     return NULL;
211 }
212
213 char *
214 prevHist(Hist *hist)
215 {
216     if (hist == NULL || hist->list == NULL)
217         return NULL;
218     if (hist->current && hist->current->prev) {
219         hist->current = hist->current->prev;
220         return (char *)hist->current->ptr;
221     }
222     return NULL;
223 }