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

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