This source file includes following definitions.
- file_history_parse_entry
- file_history_write_entry
- file_history_list_read
- file_history_list_write
- file_history_create_item
- file_history_release_item
- file_history_free_item
- show_file_history
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <config.h>
27
28 #include <stdio.h>
29
30 #include "lib/global.h"
31
32 #include "lib/fileloc.h"
33 #include "lib/mcconfig.h"
34 #include "lib/strutil.h"
35 #include "lib/util.h"
36
37 #include "file_history.h"
38
39
40
41
42
43 #define TMP_SUFFIX ".tmp"
44
45
46
47 typedef struct file_history_data_t
48 {
49 char *file_name;
50 char *file_pos;
51 } file_history_data_t;
52
53
54
55
56
57 static const char SEPARATOR[] = " ";
58
59
60
61
62
63 static void
64 file_history_parse_entry (const char *buf, GList **file_list)
65 {
66 file_history_data_t *fhd;
67 const char *s = strrchr (buf, *SEPARATOR);
68
69
70 if (s == NULL)
71 return;
72
73 fhd = g_new (file_history_data_t, 1);
74 fhd->file_name = str_unescape (buf, s - buf, "", TRUE);
75
76 const size_t len = strlen (s + 1);
77
78 fhd->file_pos = g_strndup (s + 1, len - 1);
79
80 *file_list = g_list_prepend (*file_list, fhd);
81 }
82
83
84
85 static void
86 file_history_write_entry (const file_history_data_t *fhd, GString *s)
87 {
88 {
89 char *file_name;
90
91 file_name = str_escape (fhd->file_name, -1, "", TRUE);
92 g_string_append (s, file_name);
93 g_free (file_name);
94 }
95
96 if (fhd->file_pos != NULL)
97 {
98 g_string_append_c (s, *SEPARATOR);
99 g_string_append (s, fhd->file_pos);
100 }
101 }
102
103
104
105 static GList *
106 file_history_list_read (void)
107 {
108 char *fn;
109 FILE *f;
110 char buf[MC_MAXPATHLEN + 100];
111 GList *file_list = NULL;
112
113
114 fn = mc_config_get_full_path (MC_FILEPOS_FILE);
115 if (fn == NULL)
116 return NULL;
117
118 f = fopen (fn, "r");
119 g_free (fn);
120 if (f == NULL)
121 return NULL;
122
123 while (fgets (buf, sizeof (buf), f) != NULL)
124 file_history_parse_entry (buf, &file_list);
125
126 fclose (f);
127
128 return file_list;
129 }
130
131
132
133 static void
134 file_history_list_write (const GList *file_list)
135 {
136 char *fn;
137 FILE *f;
138 gboolean write_error = FALSE;
139
140 fn = mc_config_get_full_path (MC_FILEPOS_FILE);
141 if (fn == NULL)
142 return;
143
144 mc_util_make_backup_if_possible (fn, TMP_SUFFIX);
145
146 f = fopen (fn, "w");
147 if (f != NULL)
148 {
149 GString *s;
150
151 s = g_string_sized_new (128);
152
153 for (; file_list != NULL && !write_error; file_list = g_list_next (file_list))
154 {
155 file_history_write_entry (file_list->data, s);
156 write_error = (fprintf (f, "%s\n", s->str) < 0);
157 g_string_truncate (s, 0);
158 }
159
160 g_string_free (s, TRUE);
161
162 fclose (f);
163 }
164
165 if (write_error)
166 mc_util_restore_from_backup_if_possible (fn, TMP_SUFFIX);
167 else
168 mc_util_unlink_backup_if_possible (fn, TMP_SUFFIX);
169
170 g_free (fn);
171 }
172
173
174
175 static void
176 file_history_create_item (history_descriptor_t *hd, void *data)
177 {
178 file_history_data_t *fhd = (file_history_data_t *) data;
179 size_t width;
180
181 width = str_term_width1 (fhd->file_name);
182 hd->max_width = MAX (width, hd->max_width);
183
184 listbox_add_item (hd->listbox, LISTBOX_APPEND_AT_END, 0, fhd->file_name, fhd->file_pos, TRUE);
185
186 fhd->file_pos = NULL;
187 }
188
189
190
191 static void *
192 file_history_release_item (history_descriptor_t *hd, WLEntry *le)
193 {
194 file_history_data_t *fhd;
195
196 (void) hd;
197
198 fhd = g_new (file_history_data_t, 1);
199 fhd->file_name = le->text;
200 le->text = NULL;
201 fhd->file_pos = (char *) le->data;
202 le->data = NULL;
203
204 return fhd;
205 }
206
207
208
209 static void
210 file_history_free_item (void *data)
211 {
212 file_history_data_t *fhd = (file_history_data_t *) data;
213
214 g_free (fhd->file_name);
215 g_free (fhd->file_pos);
216 g_free (fhd);
217 }
218
219
220
221
222
223
224
225
226
227
228
229
230
231 char *
232 show_file_history (const Widget *w, int *action)
233 {
234 GList *file_list;
235 size_t len;
236 history_descriptor_t hd;
237
238 file_list = file_history_list_read ();
239 if (file_list == NULL)
240 return NULL;
241
242 len = g_list_length (file_list);
243
244 file_list = g_list_last (file_list);
245
246 history_descriptor_init (&hd, w->rect.y, w->rect.x, file_list, 0);
247
248 hd.create = file_history_create_item;
249 hd.release = file_history_release_item;
250 hd.free = file_history_free_item;
251
252 history_show (&hd);
253
254 hd.list = g_list_first (hd.list);
255
256
257 if (len != g_list_length (hd.list))
258 {
259 hd.list = g_list_reverse (hd.list);
260 file_history_list_write (hd.list);
261 }
262
263 g_list_free_full (hd.list, (GDestroyNotify) file_history_free_item);
264
265 *action = hd.action;
266
267 return hd.text;
268 }
269
270