Manual pages: mcmcdiffmceditmcview

root/src/viewer/internal.h

/* [previous][next][first][last][top][bottom][index][help]  */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. mcview_offset_rounddown
  2. mcview_is_in_panel
  3. mcview_may_still_grow
  4. mcview_already_loaded
  5. mcview_get_byte_file
  6. mcview_get_byte
  7. mcview_get_byte_indexed
  8. mcview_count_backspaces
  9. mcview_is_nroff_sequence
  10. mcview_growbuf_read_all_data

   1 #ifndef MC__VIEWER_INTERNAL_H
   2 #define MC__VIEWER_INTERNAL_H
   3 
   4 #include <limits.h>  // CHAR_BIT, MB_LEN_MAX
   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"  // vfs_path_t
  14 #include "lib/util.h"     // mc_pipe_t
  15 
  16 #include "src/keymap.h"           // global_keymap_t
  17 #include "src/filemanager/dir.h"  // dir_list
  18 
  19 #include "mcviewer.h"
  20 
  21 /*** typedefs(not structures) and defined constants **********************************************/
  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 /*** enums ***************************************************************************************/
  29 
  30 /* data sources of the view */
  31 enum view_ds
  32 {
  33     DS_NONE,        // No data available
  34     DS_STDIO_PIPE,  // Data comes from a pipe using popen/pclose
  35     DS_VFS_PIPE,    // Data comes from a piped-in VFS file
  36     DS_FILE,        // Data comes from a VFS file
  37     DS_STRING       // Data comes from a string in memory
  38 };
  39 
  40 enum ccache_type
  41 {
  42     CCACHE_OFFSET,
  43     CCACHE_LINECOL
  44 };
  45 
  46 typedef enum
  47 {
  48     NROFF_TYPE_NONE,
  49     NROFF_TYPE_BOLD,
  50     NROFF_TYPE_UNDERLINE,
  51     NROFF_TYPE_BOLD_UNDERLINE
  52 } nroff_type_t;
  53 
  54 /*** structures declarations (and typedefs of structures)*****************************************/
  55 
  56 /* A node for building a change list on change_list */
  57 struct hexedit_change_node
  58 {
  59     struct hexedit_change_node *next;
  60     off_t offset;
  61     byte value;
  62 };
  63 
  64 /* A cache entry for mapping offsets into line/column pairs and vice versa.
  65  * cc_offset, cc_line, and cc_column are the 0-based values of the offset,
  66  * line and column of that cache entry. cc_nroff_column is the column
  67  * corresponding to cc_offset in nroff mode.
  68  */
  69 typedef struct
  70 {
  71     off_t cc_offset;
  72     off_t cc_line;
  73     off_t cc_column;
  74     off_t cc_nroff_column;
  75 } coord_cache_entry_t;
  76 
  77 /* TODO: find a better name. This is not actually a "state machine",
  78  * but a "state machine's state", but that sounds silly.
  79  * Could be parser_state, formatter_state... */
  80 typedef struct
  81 {
  82     off_t offset;            // The file offset at which this is the state.
  83     off_t unwrapped_column;  // Columns if the paragraph wasn't wrapped,
  84     // used for positioning TABs in wrapped lines
  85     gboolean nroff_underscore_is_underlined;  // whether _\b_ is underlined rather than bold
  86     gboolean
  87         print_lonely_combining;  // whether lonely combining marks are printed on a dotted circle
  88 } mcview_state_machine_t;
  89 
  90 struct mcview_nroff_struct;
  91 
  92 struct WView
  93 {
  94     Widget widget;
  95 
  96     vfs_path_t *filename_vpath;  // Name of the file
  97     vfs_path_t *workdir_vpath;   // Name of the working directory
  98     char *command;               // Command used to pipe data in
  99 
 100     enum view_ds datasource;  // Where the displayed data comes from
 101 
 102     // stdio pipe data source
 103     mc_pipe_t *ds_stdio_pipe;     // Output of a shell command
 104     gboolean pipe_first_err_msg;  // Show only 1st message from stderr
 105 
 106     // vfs pipe data source
 107     int ds_vfs_pipe;  // Non-seekable vfs file descriptor
 108 
 109     // vfs file data source
 110     int ds_file_fd;           // File with random access
 111     off_t ds_file_filesize;   // Size of the file
 112     off_t ds_file_offset;     // Offset of the currently loaded data
 113     byte *ds_file_data;       // Currently loaded data
 114     size_t ds_file_datalen;   // Number of valid bytes in file_data
 115     size_t ds_file_datasize;  // Number of allocated bytes in file_data
 116 
 117     // string data source
 118     byte *ds_string_data;  // The characters of the string
 119     size_t ds_string_len;  // The length of the string
 120 
 121     // Growing buffers information
 122     gboolean growbuf_in_use;      // Use the growing buffers?
 123     GPtrArray *growbuf_blockptr;  // Pointer to the block pointers
 124     size_t growbuf_lastindex;     /* Number of bytes in the last page of the
 125                                      growing buffer */
 126     gboolean growbuf_finished;    // TRUE when all data has been read.
 127 
 128     mcview_mode_flags_t mode_flags;
 129 
 130     // Hex editor modes
 131     gboolean hexedit_mode;  // Hexview or Hexedit
 132     const global_keymap_t *hex_keymap;
 133     gboolean hexview_in_text;    // Is the hexview cursor in the text area?
 134     int bytes_per_line;          // Number of bytes per line in hex mode
 135     off_t hex_cursor;            // Hexview cursor position in file
 136     gboolean hexedit_lownibble;  // Are we editing the last significant nibble?
 137     gboolean locked;             // We hold lock on current file
 138 
 139     gboolean utf8;  // It's multibyte file codeset
 140 
 141     GPtrArray *coord_cache;  // Cache for mapping offsets to cursor positions
 142 
 143     // Display information
 144     int dpy_frame_size;  // Size of the frame surrounding the real viewer
 145     off_t dpy_start;     // Offset of the displayed data (start of the paragraph in non-hex mode)
 146     off_t dpy_end;       // Offset after the displayed data
 147     off_t dpy_paragraph_skip_lines;  // Extra lines to skip in wrap mode
 148     mcview_state_machine_t
 149         dpy_state_top;  // Parser-formatter state at the topmost visible line in wrap mode
 150     mcview_state_machine_t
 151         dpy_state_bottom;     // Parser-formatter state after the bottomvisible line in wrap mode
 152     gboolean dpy_wrap_dirty;  // dpy_state_top needs to be recomputed
 153     off_t dpy_text_column;    /* Number of skipped columns in non-wrap
 154                                * text mode */
 155     int cursor_col;           // Cursor column
 156     int cursor_row;           // Cursor row
 157     struct hexedit_change_node *change_list;  // Linked list of changes
 158     WRect status_area;                        // Where the status line is displayed
 159     WRect ruler_area;                         // Where the ruler is displayed
 160     WRect data_area;                          // Where the data is displayed
 161 
 162     ssize_t force_max;  // Force a max offset, or -1
 163 
 164     int dirty;                // Number of skipped updates
 165     gboolean dpy_bbar_dirty;  // Does the button bar need to be updated?
 166 
 167     // handle of search engine
 168     mc_search_t *search;
 169     gchar *last_search_string;
 170     struct mcview_nroff_struct *search_nroff_seq;
 171     off_t search_start;  // First character to start searching from
 172     off_t search_end;    // Length of found string or 0 if none was found
 173     int search_numNeedSkipChar;
 174     // whether search conditions should be started with BOL(^) or ended with EOL($)
 175     mc_search_line_t search_line_type;
 176 
 177     // Markers
 178     int marker;       // mark to use
 179     off_t marks[10];  // 10 marks: 0..9
 180 
 181     off_t update_steps;     // The number of bytes between percent increments
 182     off_t update_activate;  // Last point where we updated the status
 183 
 184     // converter for translation of text
 185     GIConv converter;
 186 
 187     GArray *saved_bookmarks;
 188 
 189     dir_list *dir;           /* List of current directory files
 190                               * to handle CK_FileNext and CK_FilePrev commands */
 191     int *dir_idx;            /* Index of current file in dir structure.
 192                               * Pointer is used here as reference to WPanel::dir::count */
 193     vfs_path_t *ext_script;  // Temporary script file created by regex_command_for()
 194 };
 195 
 196 typedef struct mcview_nroff_struct
 197 {
 198     WView *view;
 199     off_t index;
 200     int char_length;
 201     int current_char;
 202     nroff_type_t type;
 203     nroff_type_t prev_type;
 204 } mcview_nroff_t;
 205 
 206 typedef struct mcview_search_options_t
 207 {
 208     mc_search_type_t type;
 209     gboolean case_sens;
 210     gboolean backwards;
 211     gboolean whole_words;
 212     gboolean all_codepages;
 213 } mcview_search_options_t;
 214 
 215 /*** global variables defined in .c file *********************************************************/
 216 
 217 extern mcview_search_options_t mcview_search_options;
 218 
 219 /*** declarations of public functions ************************************************************/
 220 
 221 /* actions_cmd.c:  */
 222 cb_ret_t mcview_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data);
 223 cb_ret_t mcview_dialog_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data);
 224 
 225 /* ascii.c: */
 226 void mcview_display_text (WView *view);
 227 void mcview_state_machine_init (mcview_state_machine_t *, off_t);
 228 void mcview_ascii_move_down (WView *view, off_t lines);
 229 void mcview_ascii_move_up (WView *view, off_t lines);
 230 void mcview_ascii_moveto_bol (WView *view);
 231 void mcview_ascii_moveto_eol (WView *view);
 232 
 233 #ifdef MC_ENABLE_DEBUGGING_CODE
 234 void mcview_ccache_dump (WView *view);
 235 #endif
 236 
 237 void mcview_ccache_lookup (WView *view, coord_cache_entry_t *coord, enum ccache_type lookup_what);
 238 
 239 /* datasource.c: */
 240 void mcview_set_datasource_none (WView *view);
 241 off_t mcview_get_filesize (WView *view);
 242 void mcview_update_filesize (WView *view);
 243 char *mcview_get_ptr_file (WView *view, off_t byte_index);
 244 char *mcview_get_ptr_string (WView *view, off_t byte_index);
 245 gboolean mcview_get_utf (WView *view, off_t byte_index, int *ch, int *ch_len);
 246 gboolean mcview_get_byte_string (WView *view, off_t byte_index, int *retval);
 247 gboolean mcview_get_byte_none (WView *view, off_t byte_index, int *retval);
 248 void mcview_set_byte (WView *view, off_t offset, byte b);
 249 void mcview_file_load_data (WView *view, off_t byte_index);
 250 void mcview_close_datasource (WView *view);
 251 void mcview_set_datasource_file (WView *view, int fd, const struct stat *st);
 252 gboolean mcview_load_command_output (WView *view, const char *command);
 253 void mcview_set_datasource_vfs_pipe (WView *view, int fd);
 254 void mcview_set_datasource_string (WView *view, const char *s);
 255 
 256 /* dialog.c: */
 257 gboolean mcview_dialog_search (WView *view);
 258 gboolean mcview_dialog_goto (WView *view, off_t *offset);
 259 
 260 /* display.c: */
 261 void mcview_update (WView *view);
 262 void mcview_display (WView *view);
 263 void mcview_compute_areas (WView *view);
 264 void mcview_update_bytes_per_line (WView *view);
 265 void mcview_display_toggle_ruler (WView *view);
 266 void mcview_display_frame (const WView *view);
 267 void mcview_display_clean (WView *view);
 268 void mcview_display_ruler (WView *view);
 269 
 270 /* growbuf.c: */
 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 /* hex.c: */
 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 /* lib.c: */
 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 void mcview_select_encoding (WView *view);
 294 void mcview_set_codeset (WView *view);
 295 void mcview_show_error (WView *view, const char *format, const char *filename);
 296 off_t mcview_bol (WView *view, off_t current, off_t limit);
 297 off_t mcview_eol (WView *view, off_t current);
 298 char *mcview_get_title (const WDialog *h, ssize_t width);
 299 int mcview_calc_percent (WView *view, off_t p);
 300 
 301 /* move.c */
 302 void mcview_move_up (WView *view, off_t lines);
 303 void mcview_move_down (WView *view, off_t lines);
 304 void mcview_move_left (WView *view, off_t columns);
 305 void mcview_move_right (WView *view, off_t columns);
 306 void mcview_moveto_top (WView *view);
 307 void mcview_moveto_bottom (WView *view);
 308 void mcview_moveto_bol (WView *view);
 309 void mcview_moveto_eol (WView *view);
 310 void mcview_moveto_offset (WView *view, off_t offset);
 311 void mcview_moveto (WView *view, off_t, off_t col);
 312 void mcview_coord_to_offset (WView *view, off_t *ret_offset, off_t line, off_t column);
 313 void mcview_offset_to_coord (WView *view, off_t *ret_line, off_t *ret_column, off_t offset);
 314 void mcview_place_cursor (WView *view);
 315 void mcview_moveto_match (WView *view);
 316 
 317 /* nroff.c: */
 318 int mcview__get_nroff_real_len (WView *view, off_t start, off_t length);
 319 mcview_nroff_t *mcview_nroff_seq_new_num (WView *view, off_t lc_index);
 320 mcview_nroff_t *mcview_nroff_seq_new (WView *view);
 321 void mcview_nroff_seq_free (mcview_nroff_t **nroff);
 322 nroff_type_t mcview_nroff_seq_info (mcview_nroff_t *nroff);
 323 int mcview_nroff_seq_next (mcview_nroff_t *nroff);
 324 int mcview_nroff_seq_prev (mcview_nroff_t *nroff);
 325 
 326 /* search.c: */
 327 gboolean mcview_search_init (WView *view);
 328 void mcview_search_deinit (WView *view);
 329 mc_search_cbret_t mcview_search_cmd_callback (const void *user_data, off_t char_offset,
 330                                               int *current_char);
 331 mc_search_cbret_t mcview_search_update_cmd_callback (const void *user_data, off_t char_offset);
 332 void mcview_search (WView *view, gboolean start_search);
 333 
 334 /* --------------------------------------------------------------------------------------------- */
 335 /*** inline functions ****************************************************************************/
 336 /* --------------------------------------------------------------------------------------------- */
 337 
 338 static inline off_t
 339 mcview_offset_rounddown (off_t a, off_t b)
     /* [previous][next][first][last][top][bottom][index][help]  */
 340 {
 341     g_assert (b != 0);
 342     return a - a % b;
 343 }
 344 
 345 /* --------------------------------------------------------------------------------------------- */
 346 
 347 /* {{{ Simple Primitive Functions for WView }}} */
 348 static inline gboolean
 349 mcview_is_in_panel (WView *view)
     /* [previous][next][first][last][top][bottom][index][help]  */
 350 {
 351     return (view->dpy_frame_size != 0);
 352 }
 353 
 354 /* --------------------------------------------------------------------------------------------- */
 355 
 356 static inline gboolean
 357 mcview_may_still_grow (WView *view)
     /* [previous][next][first][last][top][bottom][index][help]  */
 358 {
 359     return (view->growbuf_in_use && !view->growbuf_finished);
 360 }
 361 
 362 /* --------------------------------------------------------------------------------------------- */
 363 
 364 /* returns TRUE if the idx lies in the half-open interval
 365  * [offset; offset + size), FALSE otherwise.
 366  */
 367 static inline gboolean
 368 mcview_already_loaded (off_t offset, off_t idx, size_t size)
     /* [previous][next][first][last][top][bottom][index][help]  */
 369 {
 370     return (offset <= idx && idx - offset < (off_t) size);
 371 }
 372 
 373 /* --------------------------------------------------------------------------------------------- */
 374 
 375 static inline gboolean
 376 mcview_get_byte_file (WView *view, off_t byte_index, int *retval)
     /* [previous][next][first][last][top][bottom][index][help]  */
 377 {
 378     g_assert (view->datasource == DS_FILE);
 379 
 380     mcview_file_load_data (view, byte_index);
 381     if (mcview_already_loaded (view->ds_file_offset, byte_index, view->ds_file_datalen))
 382     {
 383         if (retval)
 384             *retval = view->ds_file_data[byte_index - view->ds_file_offset];
 385         return TRUE;
 386     }
 387     if (retval)
 388         *retval = -1;
 389     return FALSE;
 390 }
 391 
 392 /* --------------------------------------------------------------------------------------------- */
 393 
 394 static inline gboolean
 395 mcview_get_byte (WView *view, off_t offset, int *retval)
     /* [previous][next][first][last][top][bottom][index][help]  */
 396 {
 397     switch (view->datasource)
 398     {
 399     case DS_STDIO_PIPE:
 400     case DS_VFS_PIPE:
 401         return mcview_get_byte_growing_buffer (view, offset, retval);
 402     case DS_FILE:
 403         return mcview_get_byte_file (view, offset, retval);
 404     case DS_STRING:
 405         return mcview_get_byte_string (view, offset, retval);
 406     case DS_NONE:
 407         return mcview_get_byte_none (view, offset, retval);
 408     default:
 409         return FALSE;
 410     }
 411 }
 412 
 413 /* --------------------------------------------------------------------------------------------- */
 414 
 415 static inline gboolean
 416 mcview_get_byte_indexed (WView *view, off_t base, off_t ofs, int *retval)
     /* [previous][next][first][last][top][bottom][index][help]  */
 417 {
 418     if (base <= OFFSETTYPE_MAX - ofs)
 419         return mcview_get_byte (view, base + ofs, retval);
 420 
 421     if (retval != NULL)
 422         *retval = -1;
 423 
 424     return FALSE;
 425 }
 426 
 427 /* --------------------------------------------------------------------------------------------- */
 428 
 429 static inline int
 430 mcview_count_backspaces (WView *view, off_t offset)
     /* [previous][next][first][last][top][bottom][index][help]  */
 431 {
 432     int backspaces = 0;
 433     int c;
 434 
 435     while (offset >= 2 * backspaces && mcview_get_byte (view, offset - 2 * backspaces, &c)
 436            && c == '\b')
 437         backspaces++;
 438 
 439     return backspaces;
 440 }
 441 
 442 /* --------------------------------------------------------------------------------------------- */
 443 
 444 static inline gboolean
 445 mcview_is_nroff_sequence (WView *view, off_t offset)
     /* [previous][next][first][last][top][bottom][index][help]  */
 446 {
 447     int c0, c1, c2;
 448 
 449     // The following commands are ordered to speed up the calculation.
 450 
 451     if (!mcview_get_byte_indexed (view, offset, 1, &c1) || c1 != '\b')
 452         return FALSE;
 453 
 454     if (!mcview_get_byte_indexed (view, offset, 0, &c0) || !g_ascii_isprint (c0))
 455         return FALSE;
 456 
 457     if (!mcview_get_byte_indexed (view, offset, 2, &c2) || !g_ascii_isprint (c2))
 458         return FALSE;
 459 
 460     return (c0 == c2 || c0 == '_' || (c0 == '+' && c2 == 'o'));
 461 }
 462 
 463 /* --------------------------------------------------------------------------------------------- */
 464 
 465 static inline void
 466 mcview_growbuf_read_all_data (WView *view)
     /* [previous][next][first][last][top][bottom][index][help]  */
 467 {
 468     mcview_growbuf_read_until (view, OFFSETTYPE_MAX);
 469 }
 470 
 471 /* --------------------------------------------------------------------------------------------- */
 472 
 473 #endif

/* [previous][next][first][last][top][bottom][index][help]  */