added offsetof macro for platforms that do not have it
added eb_clear, eb_scratch, eb_replace, eb_delete_range added remarks about inconsistentcies check buffer readonly status in low level buffer primitives
This commit is contained in:
parent
c6514ec938
commit
e86feb3b8f
2 changed files with 128 additions and 38 deletions
85
buffer.c
85
buffer.c
|
|
@ -127,6 +127,9 @@ void eb_write(EditBuffer *b, int offset, const void *buf_arg, int size)
|
|||
int len, left;
|
||||
const u8 *buf = buf_arg;
|
||||
|
||||
if (b->flags & BF_READONLY)
|
||||
return;
|
||||
|
||||
len = eb_rw(b, offset, (void *)buf, size, 1);
|
||||
left = size - len;
|
||||
if (left > 0) {
|
||||
|
|
@ -241,9 +244,14 @@ void eb_insert_buffer(EditBuffer *dest, int dest_offset,
|
|||
Page *p, *p_start, *q;
|
||||
int size_start, len, n, page_index;
|
||||
|
||||
if (dest->flags & BF_READONLY)
|
||||
return;
|
||||
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
/* CG: should assert parameter consistency */
|
||||
|
||||
eb_addlog(dest, LOGOP_INSERT, dest_offset, size);
|
||||
|
||||
/* insert the data from the first page if it is not completely
|
||||
|
|
@ -332,6 +340,9 @@ void eb_insert_buffer(EditBuffer *dest, int dest_offset,
|
|||
have : 0 <= offset <= b->total_size */
|
||||
void eb_insert(EditBuffer *b, int offset, const void *buf, int size)
|
||||
{
|
||||
if (b->flags & BF_READONLY)
|
||||
return;
|
||||
|
||||
/* sanity checks */
|
||||
if (offset > b->total_size)
|
||||
offset = b->total_size;
|
||||
|
|
@ -353,6 +364,9 @@ void eb_delete(EditBuffer *b, int offset, int size)
|
|||
int n, len;
|
||||
Page *del_start, *p;
|
||||
|
||||
if (b->flags & BF_READONLY)
|
||||
return;
|
||||
|
||||
if (offset + size > b->total_size)
|
||||
size = b->total_size - offset;
|
||||
|
||||
|
|
@ -477,6 +491,37 @@ EditBuffer *eb_new(const char *name, int flags)
|
|||
return b;
|
||||
}
|
||||
|
||||
/* Return an empty scratch buffer, create one if necessary */
|
||||
EditBuffer *eb_scratch(const char *name)
|
||||
{
|
||||
EditBuffer *b;
|
||||
|
||||
b = eb_find(name);
|
||||
if (b != NULL) {
|
||||
eb_clear(b);
|
||||
} else {
|
||||
b = eb_new(name, 0);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void eb_clear(EditBuffer *b)
|
||||
{
|
||||
b->flags &= ~BF_READONLY;
|
||||
b->save_log = 0;
|
||||
eb_delete(b, 0, b->total_size);
|
||||
log_reset(b);
|
||||
|
||||
/* close and reset file handle */
|
||||
if (b->file_handle > 0) {
|
||||
close(b->file_handle);
|
||||
}
|
||||
b->file_handle = 0;
|
||||
|
||||
/* TODO: clear buffer structure */
|
||||
//memset(b, 0, offsetof(EditBuffer, remanent_area));
|
||||
}
|
||||
|
||||
void eb_free(EditBuffer *b)
|
||||
{
|
||||
QEmacsState *qs = &qe_state;
|
||||
|
|
@ -498,14 +543,7 @@ void eb_free(EditBuffer *b)
|
|||
}
|
||||
b->first_callback = NULL;
|
||||
|
||||
b->save_log = 0;
|
||||
eb_delete(b, 0, b->total_size);
|
||||
log_reset(b);
|
||||
|
||||
/* suppress mmap file handle */
|
||||
if (b->file_handle > 0) {
|
||||
close(b->file_handle);
|
||||
}
|
||||
eb_clear(b);
|
||||
|
||||
/* suppress from buffer list */
|
||||
pb = &qs->first_buffer;
|
||||
|
|
@ -920,7 +958,7 @@ static void get_pos(u8 *buf, int size, int *line_ptr, int *col_ptr,
|
|||
line++;
|
||||
}
|
||||
/* now compute number of chars (XXX: potential problem if out of
|
||||
block, but for UTF8 it works) */
|
||||
* block, but for UTF8 it works) */
|
||||
col = 0;
|
||||
while (lp < p1) {
|
||||
ch = s->table[*lp];
|
||||
|
|
@ -1136,6 +1174,35 @@ int eb_get_char_offset(EditBuffer *b, int offset)
|
|||
return pos;
|
||||
}
|
||||
|
||||
/* delete a range of bytes from the buffer, bounds in any order, return
|
||||
* lower bound.
|
||||
*/
|
||||
int eb_delete_range(EditBuffer *b, int p1, int p2)
|
||||
{
|
||||
if (p1 > p2) {
|
||||
int tmp = p1;
|
||||
p1 = p2;
|
||||
p2 = tmp;
|
||||
}
|
||||
eb_delete(b, p1, p2 - p1);
|
||||
return p1;
|
||||
}
|
||||
|
||||
/* replace 'size' bytes at offset 'offset' with 'size1' bytes from 'buf' */
|
||||
void eb_replace(EditBuffer *b, int offset, int size, const u8 *buf, int size1)
|
||||
{
|
||||
/* CG: behaviour is not exactly identical: mark, point and other
|
||||
* callback based offsets will be updated differently. should
|
||||
* write portion that fits and insert or delete remainder?
|
||||
*/
|
||||
if (size == size1) {
|
||||
eb_write(b, offset, buf, size1);
|
||||
} else {
|
||||
eb_delete(b, offset, size);
|
||||
eb_insert(b, offset, buf, size1);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************/
|
||||
/* buffer I/O */
|
||||
|
||||
|
|
|
|||
81
qe.h
81
qe.h
|
|
@ -63,6 +63,9 @@
|
|||
#define force_cast(type, expr) ((type)(expr))
|
||||
#endif
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(s,m) ((size_t)(&((s *)0)->m))
|
||||
#endif
|
||||
#ifndef countof
|
||||
#define countof(a) ((int)(sizeof(a) / sizeof((a)[0])))
|
||||
#endif
|
||||
|
|
@ -209,6 +212,7 @@ void css_strtolower(char *buf, int buf_size);
|
|||
void skip_spaces(const char **pp);
|
||||
|
||||
int strfind(const char *keytable, const char *str, int casefold);
|
||||
|
||||
#define stristart(str, val, ptr) qe_stristart(str, val, ptr)
|
||||
int stristart(const char *str, const char *val, const char **ptr);
|
||||
int strxstart(const char *str, const char *val, const char **ptr);
|
||||
|
|
@ -224,6 +228,9 @@ static inline unsigned int *umemcpy(unsigned int *dest,
|
|||
}
|
||||
int umemcmp(const unsigned int *s1, const unsigned int *s2, int count);
|
||||
|
||||
int strsubst(char *buf, int buf_size, const char *from,
|
||||
const char *s1, const char *s2);
|
||||
|
||||
void get_str(const char **pp, char *buf, int buf_size, const char *stop);
|
||||
int css_get_enum(const char *str, const char *enum_str);
|
||||
int compose_keys(unsigned int *keys, int *nb_keys);
|
||||
|
|
@ -319,9 +326,6 @@ static inline int buf_puts(buf_t *bp, const char *str) {
|
|||
int buf_printf(buf_t *bp, const char *fmt, ...) __attr_printf(2,3);
|
||||
int buf_putc_utf8(buf_t *bp, int c);
|
||||
|
||||
int strsubst(char *buf, int buf_size, const char *from,
|
||||
const char *s1, const char *s2);
|
||||
|
||||
/* command line option */
|
||||
#define CMD_OPT_ARG 0x0001 /* argument */
|
||||
#define CMD_OPT_STRING 0x0002 /* string */
|
||||
|
|
@ -462,7 +466,7 @@ int devanagari_log2vis(unsigned int *str, unsigned int *ctog, int len);
|
|||
|
||||
/* unicode_join.c */
|
||||
int unicode_to_glyphs(unsigned int *dst, unsigned int *char_to_glyph_pos,
|
||||
int dst_size, unsigned int *src, int src_size,
|
||||
int dst_size, unsigned int *src, int src_size,
|
||||
int reverse);
|
||||
int load_ligatures(void);
|
||||
|
||||
|
|
@ -589,7 +593,7 @@ void qe_ungrab_keys(void);
|
|||
#define MAX_PAGE_SIZE 4096
|
||||
//#define MAX_PAGE_SIZE 16
|
||||
|
||||
#define NB_LOGS_MAX 100000 /* need better way to limit undo information */
|
||||
#define NB_LOGS_MAX 100000 /* need better way to limit undo information */
|
||||
|
||||
#define PG_READ_ONLY 0x0001 /* the page is read only */
|
||||
#define PG_VALID_POS 0x0002 /* set if the nb_lines / col fields are up to date */
|
||||
|
|
@ -672,7 +676,7 @@ struct EditBuffer {
|
|||
|
||||
/* modification callbacks */
|
||||
EditBufferCallbackList *first_callback;
|
||||
|
||||
|
||||
/* asynchronous loading/saving support */
|
||||
struct BufferIOState *io_state;
|
||||
|
||||
|
|
@ -692,11 +696,9 @@ struct EditBuffer {
|
|||
|
||||
EditBuffer *next; /* next editbuffer in qe_state buffer list */
|
||||
char name[MAX_BUFFERNAME_SIZE]; /* buffer name */
|
||||
char filename[MAX_FILENAME_SIZE]; /* file name */
|
||||
char filename[MAX_FILENAME_SIZE]; /* file name */
|
||||
};
|
||||
|
||||
struct ModeProbeData;
|
||||
|
||||
/* high level buffer type handling */
|
||||
typedef struct EditBufferDataType {
|
||||
const char *name; /* name of buffer data type (text, image, ...) */
|
||||
|
|
@ -709,7 +711,7 @@ typedef struct EditBufferDataType {
|
|||
/* the log buffer is used for the undo operation */
|
||||
/* header of log operation */
|
||||
typedef struct LogBuffer {
|
||||
//u8 pad1, pad2; /* for Log buffer readability */
|
||||
//u8 pad1, pad2; /* for Log buffer readability */
|
||||
u8 op;
|
||||
u8 was_modified;
|
||||
int offset;
|
||||
|
|
@ -731,9 +733,11 @@ void eb_insert_buffer(EditBuffer *dest, int dest_offset,
|
|||
int size);
|
||||
void eb_insert(EditBuffer *b, int offset, const void *buf, int size);
|
||||
void eb_delete(EditBuffer *b, int offset, int size);
|
||||
//void eb_replace(EditBuffer *b, int offset, int size, const u8 *buf, int size1);
|
||||
void eb_replace(EditBuffer *b, int offset, int size, const u8 *buf, int size1);
|
||||
void log_reset(EditBuffer *b);
|
||||
EditBuffer *eb_new(const char *name, int flags);
|
||||
EditBuffer *eb_scratch(const char *name);
|
||||
void eb_clear(EditBuffer *b);
|
||||
void eb_free(EditBuffer *b);
|
||||
EditBuffer *eb_find(const char *name);
|
||||
EditBuffer *eb_find_file(const char *filename);
|
||||
|
|
@ -746,13 +750,14 @@ int eb_goto_pos(EditBuffer *b, int line1, int col1);
|
|||
int eb_get_pos(EditBuffer *b, int *line_ptr, int *col_ptr, int offset);
|
||||
int eb_goto_char(EditBuffer *b, int pos);
|
||||
int eb_get_char_offset(EditBuffer *b, int offset);
|
||||
//int eb_delete_range(EditBuffer *b, int p1, int p2);
|
||||
int eb_delete_range(EditBuffer *b, int p1, int p2);
|
||||
//int eb_clip_offset(EditBuffer *b, int offset);
|
||||
void do_undo(EditState *s);
|
||||
|
||||
int raw_load_buffer1(EditBuffer *b, FILE *f, int offset);
|
||||
int mmap_buffer(EditBuffer *b, const char *filename);
|
||||
int save_buffer(EditBuffer *b);
|
||||
// should rename to eb_set_buffername and eb_set_filename
|
||||
void set_buffer_name(EditBuffer *b, const char *name1);
|
||||
void set_filename(EditBuffer *b, const char *filename);
|
||||
int eb_add_callback(EditBuffer *b, EditBufferCallback cb, void *opaque);
|
||||
|
|
@ -804,9 +809,9 @@ extern EditBufferDataType raw_data_type;
|
|||
#define __exit_call __attribute__((unused, __section__ (".exitcall.exit")))
|
||||
#else
|
||||
#undef __attribute_used__
|
||||
#define __attribute_used__ __attribute__((__used__))
|
||||
#define __init_call __attribute_used__ __attribute__((__section__ (".initcall.init")))
|
||||
#define __exit_call __attribute_used__ __attribute__((__section__ (".exitcall.exit")))
|
||||
#define __attribute_used__ __attribute__((__used__))
|
||||
#define __init_call __attribute_used__ __attribute__((__section__ (".initcall.init")))
|
||||
#define __exit_call __attribute_used__ __attribute__((__section__ (".exitcall.exit")))
|
||||
#endif
|
||||
|
||||
#define qe_module_init(fn) \
|
||||
|
|
@ -874,12 +879,12 @@ struct EditState {
|
|||
int hex_mode; /* true if we are currently editing hexa */
|
||||
int unihex_mode; /* true if unihex editing (hex_mode must be true too) */
|
||||
int hex_nibble; /* current hexa nibble */
|
||||
int insert;
|
||||
int insert; /* insert/overtype mode */
|
||||
int bidir;
|
||||
int cur_rtl; /* TRUE if the cursor on over RTL chars */
|
||||
enum WrapType wrap;
|
||||
int line_numbers;
|
||||
int tab_size;
|
||||
int tab_size; /* the tab width for the window in chars */
|
||||
int indent_size;
|
||||
int indent_tabs_mode; /* if true, use tabs to indent */
|
||||
int interactive; /* true if interaction is done instead of editing
|
||||
|
|
@ -919,11 +924,13 @@ struct EditState {
|
|||
redraw should be done */
|
||||
int borders_invalid; /* true if window borders should be redrawn */
|
||||
int show_selection; /* if true, the selection is displayed */
|
||||
|
||||
/* display area info */
|
||||
int width, height;
|
||||
int ytop, xleft;
|
||||
/* full window size, including borders */
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
int flags; /* display flags */
|
||||
#define WF_POPUP 0x0001 /* popup window (with borders) */
|
||||
#define WF_MODELINE 0x0002 /* mode line must be displayed */
|
||||
|
|
@ -949,7 +956,6 @@ struct EditState {
|
|||
|
||||
#define SAVED_DATA_SIZE ((int)&((EditState *)0)->end_of_saved_data)
|
||||
|
||||
|
||||
struct DisplayState;
|
||||
|
||||
typedef struct ModeProbeData {
|
||||
|
|
@ -990,6 +996,7 @@ typedef struct ModeDef {
|
|||
int (*text_backward_offset)(EditState *, int);
|
||||
|
||||
/* common functions are defined here */
|
||||
/* TODO: Should have single move function with move type and argument */
|
||||
void (*move_up_down)(EditState *, int);
|
||||
void (*move_left_right)(EditState *, int);
|
||||
void (*move_bol)(EditState *);
|
||||
|
|
@ -999,6 +1006,7 @@ typedef struct ModeDef {
|
|||
void (*scroll_line_up_down)(EditState *, int);
|
||||
void (*write_char)(EditState *, int);
|
||||
void (*mouse_goto)(EditState *, int x, int y);
|
||||
|
||||
int mode_flags;
|
||||
#define MODEF_NOCMD 0x0001 /* do not register xxx-mode command automatically */
|
||||
EditBufferDataType *data_type; /* native buffer data type (NULL = raw) */
|
||||
|
|
@ -1061,7 +1069,7 @@ struct QEmacsState {
|
|||
EditState *first_window;
|
||||
EditState *active_window; /* window in which we edit */
|
||||
EditBuffer *first_buffer;
|
||||
//struct EditBuffer *message_buffer;
|
||||
//EditBuffer *message_buffer;
|
||||
/* global layout info : DO NOT modify these directly. do_refresh
|
||||
does it */
|
||||
int status_height;
|
||||
|
|
@ -1091,20 +1099,20 @@ struct QEmacsState {
|
|||
int yank_current;
|
||||
int argc; /* command line arguments */
|
||||
char **argv;
|
||||
char res_path[1024]; /* exported as QEPATH */
|
||||
char res_path[1024]; /* exported as QEPATH */
|
||||
char status_shadow[MAX_SCREEN_WIDTH];
|
||||
QErrorContext ec;
|
||||
char system_fonts[NB_FONT_FAMILIES][256];
|
||||
|
||||
///* global variables */
|
||||
//int it; /* last result from expression evaluator */
|
||||
////int force_tty; /* prevent graphics display (X11...) */
|
||||
//int no_config; /* prevent config file eval */
|
||||
//int force_refresh; /* force a complete screen refresh */
|
||||
//int ignore_spaces; /* ignore spaces when comparing windows */
|
||||
//int it; /* last result from expression evaluator */
|
||||
////int force_tty; /* prevent graphics display (X11...) */
|
||||
//int no_config; /* prevent config file eval */
|
||||
//int force_refresh; /* force a complete screen refresh */
|
||||
//int ignore_spaces; /* ignore spaces when comparing windows */
|
||||
//int mark_yank_region; /* set mark at opposite end of yanked block */
|
||||
//int hilite_region; /* hilite the current region when selecting */
|
||||
//int mmap_threshold; /* minimum file size for mmap */
|
||||
//int hilite_region; /* hilite the current region when selecting */
|
||||
//int mmap_threshold; /* minimum file size for mmap */
|
||||
};
|
||||
|
||||
extern QEmacsState qe_state;
|
||||
|
|
@ -1142,14 +1150,18 @@ typedef union CmdArg {
|
|||
int n;
|
||||
} CmdArg;
|
||||
|
||||
// should have enum for supported signatures
|
||||
|
||||
typedef struct CmdDef {
|
||||
unsigned short key; /* normal key */
|
||||
unsigned short alt_key; /* alternate key */
|
||||
const char *name;
|
||||
union {
|
||||
// should have union members for all supported signatures
|
||||
void *func;
|
||||
struct CmdDef *next;
|
||||
} action;
|
||||
// should be CmdArg arg;
|
||||
void *val;
|
||||
} CmdDef;
|
||||
|
||||
|
|
@ -1165,7 +1177,7 @@ typedef struct CmdDef {
|
|||
void qe_register_mode(ModeDef *m);
|
||||
void mode_completion(StringArray *cs, const char *input);
|
||||
void qe_register_cmd_table(CmdDef *cmds, const char *mode);
|
||||
void qe_register_binding(int key, const char *cmd_name,
|
||||
void qe_register_binding(int key, const char *cmd_name,
|
||||
const char *mode_names);
|
||||
CmdDef *qe_find_cmd(const char *cmd_name);
|
||||
|
||||
|
|
@ -1253,7 +1265,7 @@ void display_eol(DisplayState *s, int offset1, int offset2);
|
|||
|
||||
void display_printf(DisplayState *ds, int offset1, int offset2,
|
||||
const char *fmt, ...) __attr_printf(4,5);
|
||||
void display_printhex(DisplayState *s, int offset1, int offset2,
|
||||
void display_printhex(DisplayState *s, int offset1, int offset2,
|
||||
unsigned int h, int n);
|
||||
|
||||
static inline int display_char(DisplayState *s, int offset1, int offset2,
|
||||
|
|
@ -1330,6 +1342,7 @@ typedef struct CompletionEntry {
|
|||
} CompletionEntry;
|
||||
|
||||
void register_completion(const char *name, CompletionFunc completion_func);
|
||||
//void vput_status(EditState *s, const char *fmt, va_list ap);
|
||||
void put_status(EditState *s, const char *fmt, ...) __attr_printf(2,3);
|
||||
void put_error(EditState *s, const char *fmt, ...) __attr_printf(2,3);
|
||||
void minibuffer_edit(const char *input, const char *prompt,
|
||||
|
|
@ -1375,9 +1388,11 @@ void edit_detach(EditState *s);
|
|||
void edit_append(EditState *s, EditState *e);
|
||||
EditState *edit_find(EditBuffer *b);
|
||||
void do_refresh(EditState *s);
|
||||
// should take direction argument
|
||||
void do_other_window(EditState *s);
|
||||
void do_previous_window(EditState *s);
|
||||
void do_delete_window(EditState *s, int force);
|
||||
// should take argval
|
||||
void do_split_window(EditState *s, int horiz);
|
||||
void edit_display(QEmacsState *qs);
|
||||
void edit_invalidate(EditState *s);
|
||||
|
|
@ -1407,7 +1422,10 @@ void set_colorize_func(EditState *s, ColorizeFunc colorize_func);
|
|||
int get_colorized_line(EditState *s, unsigned int *buf, int buf_size,
|
||||
int offset1, int line_num);
|
||||
|
||||
// should take argval
|
||||
void do_char(EditState *s, int key);
|
||||
// bad name!
|
||||
// void do_set_mode(EditState *s, const char *mode_name);
|
||||
void do_set_mode(EditState *s, ModeDef *m, ModeSavedData *saved_data);
|
||||
void text_move_left_right_visual(EditState *s, int dir);
|
||||
void text_move_word_left_right(EditState *s, int dir);
|
||||
|
|
@ -1417,6 +1435,7 @@ void text_write_char(EditState *s, int key);
|
|||
void do_return(EditState *s);
|
||||
void do_backspace(EditState *s, int argval);
|
||||
void do_delete_char(EditState *s, int argval);
|
||||
// should take argval
|
||||
void do_tab(EditState *s);
|
||||
EditBuffer *new_yank_buffer(void);
|
||||
void do_append_next_kill(EditState *s);
|
||||
|
|
@ -1459,12 +1478,15 @@ void do_delete_word(EditState *s, int dir);
|
|||
int cursor_func(DisplayState *ds,
|
||||
int offset1, int offset2, int line_num,
|
||||
int x, int y, int w, int h, int hex_mode);
|
||||
// should take argval
|
||||
void do_scroll_up_down(EditState *s, int dir);
|
||||
void perform_scroll_up_down(EditState *s, int h);
|
||||
void do_center_cursor(EditState *s);
|
||||
// should take argval
|
||||
void do_quote(EditState *s);
|
||||
void do_insert(EditState *s);
|
||||
void do_open_line(EditState *s);
|
||||
// should take argval
|
||||
void do_set_mark(EditState *s);
|
||||
void do_mark_whole_buffer(EditState *s);
|
||||
void do_yank(EditState *s);
|
||||
|
|
@ -1535,6 +1557,7 @@ int parse_command_line(int argc, char **argv);
|
|||
void set_user_option(const char *user);
|
||||
|
||||
/* hex.c */
|
||||
|
||||
void hex_write_char(EditState *s, int key);
|
||||
|
||||
/* list.c */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue