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 char *file_name;
89
90 file_name = str_escape (fhd->file_name, -1, "", TRUE);
91 g_string_append (s, file_name);
92 g_free (file_name);
93
94 if (fhd->file_pos != NULL)
95 {
96 g_string_append_c (s, *SEPARATOR);
97 g_string_append (s, fhd->file_pos);
98 }
99 }
100
101
102
103 static GList *
104 file_history_list_read (void)
105 {
106 char *fn;
107 FILE *f;
108 char buf[MC_MAXPATHLEN + 100];
109 GList *file_list = NULL;
110
111
112 fn = mc_config_get_full_path (MC_FILEPOS_FILE);
113 if (fn == NULL)
114 return NULL;
115
116 f = fopen (fn, "r");
117 g_free (fn);
118 if (f == NULL)
119 return NULL;
120
121 while (fgets (buf, sizeof (buf), f) != NULL)
122 file_history_parse_entry (buf, &file_list);
123
124 fclose (f);
125
126 return file_list;
127 }
128
129
130
131 static void
132 file_history_list_write (const GList *file_list)
133 {
134 char *fn;
135 FILE *f;
136 gboolean write_error = FALSE;
137
138 fn = mc_config_get_full_path (MC_FILEPOS_FILE);
139 if (fn == NULL)
140 return;
141
142 mc_util_make_backup_if_possible (fn, TMP_SUFFIX);
143
144 f = fopen (fn, "w");
145 if (f != NULL)
146 {
147 GString *s;
148
149 s = g_string_sized_new (128);
150
151 for (; file_list != NULL && !write_error; file_list = g_list_next (file_list))
152 {
153 file_history_write_entry (file_list->data, s);
154 write_error = (fprintf (f, "%s\n", s->str) < 0);
155 g_string_truncate (s, 0);
156 }
157
158 g_string_free (s, TRUE);
159
160 fclose (f);
161 }
162
163 if (write_error)
164 mc_util_restore_from_backup_if_possible (fn, TMP_SUFFIX);
165 else
166 mc_util_unlink_backup_if_possible (fn, TMP_SUFFIX);
167
168 g_free (fn);
169 }
170
171
172
173 static void
174 file_history_create_item (history_descriptor_t *hd, void *data)
175 {
176 file_history_data_t *fhd = (file_history_data_t *) data;
177 size_t width;
178
179 width = str_term_width1 (fhd->file_name);
180 hd->max_width = MAX (width, hd->max_width);
181
182 listbox_add_item (hd->listbox, LISTBOX_APPEND_AT_END, 0, fhd->file_name, fhd->file_pos, TRUE);
183
184 fhd->file_pos = NULL;
185 }
186
187
188
189 static void *
190 file_history_release_item (history_descriptor_t *hd, WLEntry *le)
191 {
192 file_history_data_t *fhd;
193
194 (void) hd;
195
196 fhd = g_new (file_history_data_t, 1);
197 fhd->file_name = le->text;
198 le->text = NULL;
199 fhd->file_pos = (char *) le->data;
200 le->data = NULL;
201
202 return fhd;
203 }
204
205
206
207 static void
208 file_history_free_item (void *data)
209 {
210 file_history_data_t *fhd = (file_history_data_t *) data;
211
212 g_free (fhd->file_name);
213 g_free (fhd->file_pos);
214 g_free (fhd);
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228
229 char *
230 show_file_history (const Widget *w, int *action)
231 {
232 GList *file_list;
233 size_t len;
234 history_descriptor_t hd;
235
236 file_list = file_history_list_read ();
237 if (file_list == NULL)
238 return NULL;
239
240 len = g_list_length (file_list);
241
242 file_list = g_list_last (file_list);
243
244 history_descriptor_init (&hd, w->rect.y, w->rect.x, file_list, 0);
245
246 hd.create = file_history_create_item;
247 hd.release = file_history_release_item;
248 hd.free = file_history_free_item;
249
250 history_show (&hd);
251
252 hd.list = g_list_first (hd.list);
253
254
255 if (len != g_list_length (hd.list))
256 {
257 hd.list = g_list_reverse (hd.list);
258 file_history_list_write (hd.list);
259 }
260
261 g_list_free_full (hd.list, (GDestroyNotify) file_history_free_item);
262
263 *action = hd.action;
264
265 return hd.text;
266 }
267
268