This source file includes following definitions.
- mcview_offset_rounddown
- mcview_is_in_panel
- mcview_may_still_grow
- mcview_already_loaded
- mcview_get_byte_file
- mcview_get_byte
- mcview_get_byte_indexed
- mcview_count_backspaces
- mcview_is_nroff_sequence
- mcview_growbuf_read_all_data
1 #ifndef MC__VIEWER_INTERNAL_H
2 #define MC__VIEWER_INTERNAL_H
3
4 #include <limits.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <sys/types.h>
8
9 #include "lib/global.h"
10
11 #include "lib/search.h"
12 #include "lib/widget.h"
13 #include "lib/vfs/vfs.h"
14 #include "lib/util.h"
15
16 #include "src/keymap.h"
17 #include "src/filemanager/dir.h"
18
19 #include "mcviewer.h"
20
21
22
23 #define OFF_T_BITWIDTH ((unsigned int) (sizeof (off_t) * CHAR_BIT - 1))
24 #define OFFSETTYPE_MAX (((off_t) 1 << (OFF_T_BITWIDTH - 1)) - 1)
25
26 typedef unsigned char byte;
27
28
29
30
31 enum view_ds
32 {
33 DS_NONE,
34 DS_STDIO_PIPE,
35 DS_VFS_PIPE,
36 DS_FILE,
37 DS_STRING
38 };
39
40 enum ccache_type
41 {
42 CCACHE_OFFSET,
43 CCACHE_LINECOL
44 };
45
46 typedef enum
47 {
48 NROFF_TYPE_NONE = 0,
49 NROFF_TYPE_BOLD = 1,
50 NROFF_TYPE_UNDERLINE = 2
51 } nroff_type_t;
52
53
54
55
56 struct hexedit_change_node
57 {
58 struct hexedit_change_node *next;
59 off_t offset;
60 byte value;
61 };
62
63
64
65
66
67
68 typedef struct
69 {
70 off_t cc_offset;
71 off_t cc_line;
72 off_t cc_column;
73 off_t cc_nroff_column;
74 } coord_cache_entry_t;
75
76
77
78
79 typedef struct
80 {
81 off_t offset;
82 off_t unwrapped_column;
83
84 gboolean nroff_underscore_is_underlined;
85 gboolean
86 print_lonely_combining;
87 } mcview_state_machine_t;
88
89 struct mcview_nroff_struct;
90
91 struct WView
92 {
93 Widget widget;
94
95 vfs_path_t *filename_vpath;
96 vfs_path_t *workdir_vpath;
97 char *command;
98
99 enum view_ds datasource;
100
101
102 mc_pipe_t *ds_stdio_pipe;
103 gboolean pipe_first_err_msg;
104
105
106 int ds_vfs_pipe;
107
108
109 int ds_file_fd;
110 off_t ds_file_filesize;
111 off_t ds_file_offset;
112 byte *ds_file_data;
113 size_t ds_file_datalen;
114 size_t ds_file_datasize;
115
116
117 byte *ds_string_data;
118 size_t ds_string_len;
119
120
121 gboolean growbuf_in_use;
122 GPtrArray *growbuf_blockptr;
123 size_t growbuf_lastindex;
124
125 gboolean growbuf_finished;
126
127 mcview_mode_flags_t mode_flags;
128
129
130 gboolean hexedit_mode;
131 const global_keymap_t *hex_keymap;
132 gboolean hexview_in_text;
133 int bytes_per_line;
134 off_t hex_cursor;
135 gboolean hexedit_lownibble;
136 gboolean locked;
137
138 #ifdef HAVE_CHARSET
139 gboolean utf8;
140 #endif
141
142 GPtrArray *coord_cache;
143
144
145 int dpy_frame_size;
146 off_t dpy_start;
147 off_t dpy_end;
148 off_t dpy_paragraph_skip_lines;
149 mcview_state_machine_t
150 dpy_state_top;
151 mcview_state_machine_t
152 dpy_state_bottom;
153 gboolean dpy_wrap_dirty;
154 off_t dpy_text_column;
155
156 int cursor_col;
157 int cursor_row;
158 struct hexedit_change_node *change_list;
159 WRect status_area;
160 WRect ruler_area;
161 WRect data_area;
162
163 ssize_t force_max;
164
165 int dirty;
166 gboolean dpy_bbar_dirty;
167
168
169 mc_search_t *search;
170 gchar *last_search_string;
171 struct mcview_nroff_struct *search_nroff_seq;
172 off_t search_start;
173 off_t search_end;
174 int search_numNeedSkipChar;
175
176 mc_search_line_t search_line_type;
177
178
179 int marker;
180 off_t marks[10];
181
182 off_t update_steps;
183 off_t update_activate;
184
185
186 GIConv converter;
187
188 GArray *saved_bookmarks;
189
190 dir_list *dir;
191
192 int *dir_idx;
193
194 vfs_path_t *ext_script;
195 };
196
197 typedef struct mcview_nroff_struct
198 {
199 WView *view;
200 off_t index;
201 int char_length;
202 int current_char;
203 nroff_type_t type;
204 nroff_type_t prev_type;
205 } mcview_nroff_t;
206
207 typedef struct mcview_search_options_t
208 {
209 mc_search_type_t type;
210 gboolean case_sens;
211 gboolean backwards;
212 gboolean whole_words;
213 gboolean all_codepages;
214 } mcview_search_options_t;
215
216
217
218 extern mcview_search_options_t mcview_search_options;
219
220
221
222
223 cb_ret_t mcview_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data);
224 cb_ret_t mcview_dialog_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data);
225
226
227 void mcview_display_text (WView *view);
228 void mcview_state_machine_init (mcview_state_machine_t *, off_t);
229 void mcview_ascii_move_down (WView *view, off_t lines);
230 void mcview_ascii_move_up (WView *view, off_t lines);
231 void mcview_ascii_moveto_bol (WView *view);
232 void mcview_ascii_moveto_eol (WView *view);
233
234 #ifdef MC_ENABLE_DEBUGGING_CODE
235 void mcview_ccache_dump (WView *view);
236 #endif
237
238 void mcview_ccache_lookup (WView *view, coord_cache_entry_t *coord, enum ccache_type lookup_what);
239
240
241 void mcview_set_datasource_none (WView *view);
242 off_t mcview_get_filesize (WView *view);
243 void mcview_update_filesize (WView *view);
244 char *mcview_get_ptr_file (WView *view, off_t byte_index);
245 char *mcview_get_ptr_string (WView *view, off_t byte_index);
246 gboolean mcview_get_utf (WView *view, off_t byte_index, int *ch, int *ch_len);
247 gboolean mcview_get_byte_string (WView *view, off_t byte_index, int *retval);
248 gboolean mcview_get_byte_none (WView *view, off_t byte_index, int *retval);
249 void mcview_set_byte (WView *view, off_t offset, byte b);
250 void mcview_file_load_data (WView *view, off_t byte_index);
251 void mcview_close_datasource (WView *view);
252 void mcview_set_datasource_file (WView *view, int fd, const struct stat *st);
253 gboolean mcview_load_command_output (WView *view, const char *command);
254 void mcview_set_datasource_vfs_pipe (WView *view, int fd);
255 void mcview_set_datasource_string (WView *view, const char *s);
256
257
258 gboolean mcview_dialog_search (WView *view);
259 gboolean mcview_dialog_goto (WView *view, off_t *offset);
260
261
262 void mcview_update (WView *view);
263 void mcview_display (WView *view);
264 void mcview_compute_areas (WView *view);
265 void mcview_update_bytes_per_line (WView *view);
266 void mcview_display_toggle_ruler (WView *view);
267 void mcview_display_clean (WView *view);
268 void mcview_display_ruler (WView *view);
269
270
271 void mcview_growbuf_init (WView *view);
272 void mcview_growbuf_done (WView *view);
273 void mcview_growbuf_free (WView *view);
274 off_t mcview_growbuf_filesize (WView *view);
275 void mcview_growbuf_read_until (WView *view, off_t ofs);
276 gboolean mcview_get_byte_growing_buffer (WView *view, off_t byte_index, int *retval);
277 char *mcview_get_ptr_growing_buffer (WView *view, off_t byte_index);
278
279
280 void mcview_display_hex (WView *view);
281 gboolean mcview_hexedit_save_changes (WView *view);
282 void mcview_toggle_hexedit_mode (WView *view);
283 void mcview_hexedit_free_change_list (WView *view);
284 void mcview_enqueue_change (struct hexedit_change_node **head, struct hexedit_change_node *node);
285
286
287 void mcview_toggle_magic_mode (WView *view);
288 void mcview_toggle_wrap_mode (WView *view);
289 void mcview_toggle_nroff_mode (WView *view);
290 void mcview_toggle_hex_mode (WView *view);
291 void mcview_init (WView *view);
292 void mcview_done (WView *view);
293 #ifdef HAVE_CHARSET
294 void mcview_select_encoding (WView *view);
295 void mcview_set_codeset (WView *view);
296 #endif
297 void mcview_show_error (WView *view, const char *error);
298 off_t mcview_bol (WView *view, off_t current, off_t limit);
299 off_t mcview_eol (WView *view, off_t current);
300 char *mcview_get_title (const WDialog *h, size_t len);
301 int mcview_calc_percent (WView *view, off_t p);
302
303
304 void mcview_move_up (WView *view, off_t lines);
305 void mcview_move_down (WView *view, off_t lines);
306 void mcview_move_left (WView *view, off_t columns);
307 void mcview_move_right (WView *view, off_t columns);
308 void mcview_moveto_top (WView *view);
309 void mcview_moveto_bottom (WView *view);
310 void mcview_moveto_bol (WView *view);
311 void mcview_moveto_eol (WView *view);
312 void mcview_moveto_offset (WView *view, off_t offset);
313 void mcview_moveto (WView *view, off_t, off_t col);
314 void mcview_coord_to_offset (WView *view, off_t *ret_offset, off_t line, off_t column);
315 void mcview_offset_to_coord (WView *view, off_t *ret_line, off_t *ret_column, off_t offset);
316 void mcview_place_cursor (WView *view);
317 void mcview_moveto_match (WView *view);
318
319
320 int mcview__get_nroff_real_len (WView *view, off_t start, off_t length);
321 mcview_nroff_t *mcview_nroff_seq_new_num (WView *view, off_t lc_index);
322 mcview_nroff_t *mcview_nroff_seq_new (WView *view);
323 void mcview_nroff_seq_free (mcview_nroff_t **nroff);
324 nroff_type_t mcview_nroff_seq_info (mcview_nroff_t *nroff);
325 int mcview_nroff_seq_next (mcview_nroff_t *nroff);
326 int mcview_nroff_seq_prev (mcview_nroff_t *nroff);
327
328
329 gboolean mcview_search_init (WView *view);
330 void mcview_search_deinit (WView *view);
331 mc_search_cbret_t mcview_search_cmd_callback (const void *user_data, off_t char_offset,
332 int *current_char);
333 mc_search_cbret_t mcview_search_update_cmd_callback (const void *user_data, off_t char_offset);
334 void mcview_search (WView *view, gboolean start_search);
335
336
337
338
339
340 static inline off_t
341 mcview_offset_rounddown (off_t a, off_t b)
342 {
343 g_assert (b != 0);
344 return a - a % b;
345 }
346
347
348
349
350 static inline gboolean
351 mcview_is_in_panel (WView *view)
352 {
353 return (view->dpy_frame_size != 0);
354 }
355
356
357
358 static inline gboolean
359 mcview_may_still_grow (WView *view)
360 {
361 return (view->growbuf_in_use && !view->growbuf_finished);
362 }
363
364
365
366
367
368
369 static inline gboolean
370 mcview_already_loaded (off_t offset, off_t idx, size_t size)
371 {
372 return (offset <= idx && idx - offset < (off_t) size);
373 }
374
375
376
377 static inline gboolean
378 mcview_get_byte_file (WView *view, off_t byte_index, int *retval)
379 {
380 g_assert (view->datasource == DS_FILE);
381
382 mcview_file_load_data (view, byte_index);
383 if (mcview_already_loaded (view->ds_file_offset, byte_index, view->ds_file_datalen))
384 {
385 if (retval)
386 *retval = view->ds_file_data[byte_index - view->ds_file_offset];
387 return TRUE;
388 }
389 if (retval)
390 *retval = -1;
391 return FALSE;
392 }
393
394
395
396 static inline gboolean
397 mcview_get_byte (WView *view, off_t offset, int *retval)
398 {
399 switch (view->datasource)
400 {
401 case DS_STDIO_PIPE:
402 case DS_VFS_PIPE:
403 return mcview_get_byte_growing_buffer (view, offset, retval);
404 case DS_FILE:
405 return mcview_get_byte_file (view, offset, retval);
406 case DS_STRING:
407 return mcview_get_byte_string (view, offset, retval);
408 case DS_NONE:
409 return mcview_get_byte_none (view, offset, retval);
410 default:
411 return FALSE;
412 }
413 }
414
415
416
417 static inline gboolean
418 mcview_get_byte_indexed (WView *view, off_t base, off_t ofs, int *retval)
419 {
420 if (base <= OFFSETTYPE_MAX - ofs)
421 return mcview_get_byte (view, base + ofs, retval);
422
423 if (retval != NULL)
424 *retval = -1;
425
426 return FALSE;
427 }
428
429
430
431 static inline int
432 mcview_count_backspaces (WView *view, off_t offset)
433 {
434 int backspaces = 0;
435 int c;
436
437 while (offset >= 2 * backspaces && mcview_get_byte (view, offset - 2 * backspaces, &c)
438 && c == '\b')
439 backspaces++;
440
441 return backspaces;
442 }
443
444
445
446 static inline gboolean
447 mcview_is_nroff_sequence (WView *view, off_t offset)
448 {
449 int c0, c1, c2;
450
451
452
453 if (!mcview_get_byte_indexed (view, offset, 1, &c1) || c1 != '\b')
454 return FALSE;
455
456 if (!mcview_get_byte_indexed (view, offset, 0, &c0) || !g_ascii_isprint (c0))
457 return FALSE;
458
459 if (!mcview_get_byte_indexed (view, offset, 2, &c2) || !g_ascii_isprint (c2))
460 return FALSE;
461
462 return (c0 == c2 || c0 == '_' || (c0 == '+' && c2 == 'o'));
463 }
464
465
466
467 static inline void
468 mcview_growbuf_read_all_data (WView *view)
469 {
470 mcview_growbuf_read_until (view, OFFSETTYPE_MAX);
471 }
472
473
474
475 #endif