mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Cleanup by moving various (mostly horrible) little bits handling UTF-8 grid
data into functions in a new file, grid-utf8.c, and use sizeof intead of UTF8_DATA. Also nuke trailing whitespace from tmux.1, reminded by jmc.
This commit is contained in:
		
							
								
								
									
										2
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								Makefile
									
									
									
									
									
								
							| @@ -30,7 +30,7 @@ SRCS=	attributes.c cfg.c client.c clock.c \ | |||||||
| 	cmd-set-environment.c cmd-show-environment.c cmd-choose-client.c \ | 	cmd-set-environment.c cmd-show-environment.c cmd-choose-client.c \ | ||||||
| 	cmd-up-pane.c cmd-display-message.c cmd-display-panes.c \ | 	cmd-up-pane.c cmd-display-message.c cmd-display-panes.c \ | ||||||
| 	cmd-pipe-pane.c cmd.c \ | 	cmd-pipe-pane.c cmd.c \ | ||||||
| 	colour.c environ.c grid-view.c grid.c input-keys.c \ | 	colour.c environ.c grid-view.c grid-utf8.c grid.c input-keys.c \ | ||||||
| 	imsg.c imsg-buffer.c input.c key-bindings.c key-string.c \ | 	imsg.c imsg-buffer.c input.c key-bindings.c key-string.c \ | ||||||
| 	layout-set.c layout.c log.c job.c \ | 	layout-set.c layout.c log.c job.c \ | ||||||
| 	mode-key.c names.c options-cmd.c options.c paste.c procname.c \ | 	mode-key.c names.c options-cmd.c options.c paste.c procname.c \ | ||||||
|   | |||||||
							
								
								
									
										96
									
								
								grid-utf8.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								grid-utf8.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | |||||||
|  | /* $OpenBSD$ */ | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
|  |  * | ||||||
|  |  * Permission to use, copy, modify, and distribute this software for any | ||||||
|  |  * purpose with or without fee is hereby granted, provided that the above | ||||||
|  |  * copyright notice and this permission notice appear in all copies. | ||||||
|  |  * | ||||||
|  |  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||||
|  |  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||||
|  |  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||||
|  |  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||||
|  |  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER | ||||||
|  |  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING | ||||||
|  |  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #include <sys/types.h> | ||||||
|  |  | ||||||
|  | #include <string.h> | ||||||
|  |  | ||||||
|  | #include "tmux.h" | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * Grid UTF-8 utility functions. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | /* Calculate UTF-8 grid cell size. Data is terminated by 0xff. */ | ||||||
|  | size_t | ||||||
|  | grid_utf8_size(const struct grid_utf8 *gu) | ||||||
|  | { | ||||||
|  | 	size_t	size; | ||||||
|  |  | ||||||
|  | 	for (size = 0; size < sizeof gu->data; size++) { | ||||||
|  | 		if (gu->data[size] == 0xff) | ||||||
|  | 			break; | ||||||
|  | 	} | ||||||
|  | 	return (size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Copy UTF-8 out into a buffer. */ | ||||||
|  | size_t | ||||||
|  | grid_utf8_copy(const struct grid_utf8 *gu, char *buf, size_t len) | ||||||
|  | { | ||||||
|  | 	size_t	size; | ||||||
|  |  | ||||||
|  | 	size = grid_utf8_size(gu); | ||||||
|  | 	if (size > len) | ||||||
|  | 		fatalx("UTF-8 copy overflow"); | ||||||
|  | 	memcpy(buf, gu->data, size); | ||||||
|  | 	return (size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Set UTF-8 grid data from input UTF-8. */ | ||||||
|  | void | ||||||
|  | grid_utf8_set(struct grid_utf8 *gu, const struct utf8_data *utf8data) | ||||||
|  | { | ||||||
|  | 	if (utf8data->size == 0) | ||||||
|  | 		fatalx("UTF-8 data empty"); | ||||||
|  | 	if (utf8data->size > sizeof gu->data) | ||||||
|  | 		fatalx("UTF-8 data too long"); | ||||||
|  | 	memcpy(gu->data, utf8data->data, utf8data->size); | ||||||
|  | 	if (utf8data->size != sizeof gu->data) | ||||||
|  | 		gu->data[utf8data->size] = 0xff; | ||||||
|  | 	gu->width = utf8data->width; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Append UTF-8 character onto the cell data (for combined characters). */ | ||||||
|  | int | ||||||
|  | grid_utf8_append(struct grid_utf8 *gu, const struct utf8_data *utf8data) | ||||||
|  | { | ||||||
|  | 	size_t	old_size; | ||||||
|  |  | ||||||
|  | 	old_size = grid_utf8_size(gu); | ||||||
|  | 	if (old_size + utf8data->size > sizeof gu->data) | ||||||
|  | 		return (-1); | ||||||
|  | 	memcpy(gu->data + old_size, utf8data->data, utf8data->size); | ||||||
|  | 	if (old_size + utf8data->size != sizeof gu->data) | ||||||
|  | 		gu->data[old_size + utf8data->size] = 0xff; | ||||||
|  | 	return (0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Compare two UTF-8 cells. */ | ||||||
|  | int | ||||||
|  | grid_utf8_compare(const struct grid_utf8 *gu1, const struct grid_utf8 *gu2) | ||||||
|  | { | ||||||
|  | 	size_t	size; | ||||||
|  |  | ||||||
|  | 	size = grid_utf8_size(gu1); | ||||||
|  | 	if (size != grid_utf8_size(gu2)) | ||||||
|  | 		return (0); | ||||||
|  | 	if (memcmp(gu1->data, gu2->data, size) != 0) | ||||||
|  | 		return (0); | ||||||
|  | 	return (1);	 | ||||||
|  | } | ||||||
							
								
								
									
										16
									
								
								grid.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								grid.c
									
									
									
									
									
								
							| @@ -502,8 +502,8 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx) | |||||||
|  	const struct grid_cell	*gc; |  	const struct grid_cell	*gc; | ||||||
|  	const struct grid_utf8	*gu; |  	const struct grid_utf8	*gu; | ||||||
| 	char			*buf; | 	char			*buf; | ||||||
| 	size_t			 len, off; | 	size_t			 len, off, size; | ||||||
| 	u_int			 xx, i; | 	u_int			 xx; | ||||||
|  |  | ||||||
| 	GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx); | 	GRID_DEBUG(gd, "px=%u, py=%u, nx=%u", px, py, nx); | ||||||
|  |  | ||||||
| @@ -517,17 +517,15 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx) | |||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
| 		if (gc->flags & GRID_FLAG_UTF8) { | 		if (gc->flags & GRID_FLAG_UTF8) { | ||||||
| 			while (len < off + UTF8_SIZE + 1) { | 			gu = grid_peek_utf8(gd, xx, py); | ||||||
|  |  | ||||||
|  | 			size = grid_utf8_size(gu); | ||||||
|  | 			while (len < off + size + 1) { | ||||||
| 				buf = xrealloc(buf, 2, len); | 				buf = xrealloc(buf, 2, len); | ||||||
| 				len *= 2; | 				len *= 2; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			gu = grid_peek_utf8(gd, xx, py); | 			off += grid_utf8_copy(gu, buf + off, len - off); | ||||||
| 			for (i = 0; i < UTF8_SIZE; i++) { |  | ||||||
| 				if (gu->data[i] == 0xff) |  | ||||||
| 					break; |  | ||||||
| 				buf[off++] = gu->data[i]; |  | ||||||
| 			} |  | ||||||
| 		} else { | 		} else { | ||||||
| 			while (len < off + 2) { | 			while (len < off + 2) { | ||||||
| 				buf = xrealloc(buf, 2, len); | 				buf = xrealloc(buf, 2, len); | ||||||
|   | |||||||
| @@ -354,7 +354,7 @@ screen_write_copy(struct screen_write_ctx *ctx, | |||||||
| 	const struct grid_cell	*gc; | 	const struct grid_cell	*gc; | ||||||
| 	const struct grid_utf8	*gu; | 	const struct grid_utf8	*gu; | ||||||
| 	struct utf8_data	 utf8data; | 	struct utf8_data	 utf8data; | ||||||
| 	u_int		 	 xx, yy, cx, cy, ax, bx, i; | 	u_int		 	 xx, yy, cx, cy, ax, bx; | ||||||
|  |  | ||||||
| 	cx = s->cx; | 	cx = s->cx; | ||||||
| 	cy = s->cy; | 	cy = s->cy; | ||||||
| @@ -381,18 +381,15 @@ screen_write_copy(struct screen_write_ctx *ctx, | |||||||
| 					gc = &grid_default_cell; | 					gc = &grid_default_cell; | ||||||
| 				else | 				else | ||||||
| 					gc = &gl->celldata[xx]; | 					gc = &gl->celldata[xx]; | ||||||
| 				if (gc->flags & GRID_FLAG_UTF8) { | 				if (!(gc->flags & GRID_FLAG_UTF8)) { | ||||||
|  | 					screen_write_cell(ctx, gc, NULL); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 				/* Reinject the UTF-8 sequence. */ | ||||||
| 				gu = &gl->utf8data[xx]; | 				gu = &gl->utf8data[xx]; | ||||||
| 					memcpy(utf8data.data, | 				utf8data.size = grid_utf8_copy( | ||||||
| 					    gu->data, sizeof utf8data.data); | 				    gu, utf8data.data, sizeof utf8data.data); | ||||||
| 				utf8data.width = gu->width; | 				utf8data.width = gu->width; | ||||||
| 					utf8data.size = 0; |  | ||||||
| 					for (i = 0; i < UTF8_SIZE; i++) { |  | ||||||
| 						if (gu->data[i] == 0xff) |  | ||||||
| 							break; |  | ||||||
| 						utf8data.size++; |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 				screen_write_cell(ctx, gc, &utf8data); | 				screen_write_cell(ctx, gc, &utf8data); | ||||||
| 			} | 			} | ||||||
| 			if (px + nx == gd->sx && px + nx > gl->cellsize) | 			if (px + nx == gd->sx && px + nx > gl->cellsize) | ||||||
| @@ -1037,13 +1034,7 @@ screen_write_cell(struct screen_write_ctx *ctx, | |||||||
| 	grid_view_set_cell(gd, s->cx, s->cy, gc); | 	grid_view_set_cell(gd, s->cx, s->cy, gc); | ||||||
| 	if (gc->flags & GRID_FLAG_UTF8) { | 	if (gc->flags & GRID_FLAG_UTF8) { | ||||||
| 		/* Construct UTF-8 and write it. */ | 		/* Construct UTF-8 and write it. */ | ||||||
| 		gu.width = utf8data->width; | 		grid_utf8_set(&gu, utf8data); | ||||||
| 		memset(gu.data, 0xff, sizeof gu.data); |  | ||||||
| 		if (utf8data->size == 0) |  | ||||||
| 			fatalx("UTF-8 data empty"); |  | ||||||
| 		if (utf8data->size > sizeof gu.data) |  | ||||||
| 			fatalx("UTF-8 data overflow"); |  | ||||||
| 		memcpy(gu.data, utf8data->data, utf8data->size); |  | ||||||
| 		grid_view_set_utf8(gd, s->cx, s->cy, &gu); | 		grid_view_set_utf8(gd, s->cx, s->cy, &gu); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -1080,7 +1071,7 @@ screen_write_combine( | |||||||
| 	struct grid		*gd = s->grid; | 	struct grid		*gd = s->grid; | ||||||
| 	struct grid_cell	*gc; | 	struct grid_cell	*gc; | ||||||
| 	struct grid_utf8	*gu, tmp_gu; | 	struct grid_utf8	*gu, tmp_gu; | ||||||
| 	u_int			 i, old_size; | 	u_int			 i; | ||||||
|  |  | ||||||
| 	/* Can't combine if at 0. */ | 	/* Can't combine if at 0. */ | ||||||
| 	if (s->cx == 0) | 	if (s->cx == 0) | ||||||
| @@ -1093,35 +1084,30 @@ screen_write_combine( | |||||||
| 	/* Retrieve the previous cell and convert to UTF-8 if not already. */ | 	/* Retrieve the previous cell and convert to UTF-8 if not already. */ | ||||||
| 	gc = grid_view_get_cell(gd, s->cx - 1, s->cy); | 	gc = grid_view_get_cell(gd, s->cx - 1, s->cy); | ||||||
| 	if (!(gc->flags & GRID_FLAG_UTF8)) { | 	if (!(gc->flags & GRID_FLAG_UTF8)) { | ||||||
| 		memset(&tmp_gu.data, 0xff, sizeof tmp_gu.data); | 		tmp_gu.data[0] = gc->data; | ||||||
| 		*tmp_gu.data = gc->data; | 		tmp_gu.data[1] = 0xff; | ||||||
| 		tmp_gu.width = 1; | 		tmp_gu.width = 1; | ||||||
|  |  | ||||||
| 		grid_view_set_utf8(gd, s->cx - 1, s->cy, &tmp_gu); | 		grid_view_set_utf8(gd, s->cx - 1, s->cy, &tmp_gu); | ||||||
| 		gc->flags |= GRID_FLAG_UTF8; | 		gc->flags |= GRID_FLAG_UTF8; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* Get the previous cell's UTF-8 data and its size. */ | 	/* Append the current cell. */ | ||||||
| 	gu = grid_view_get_utf8(gd, s->cx - 1, s->cy); | 	gu = grid_view_get_utf8(gd, s->cx - 1, s->cy); | ||||||
| 	for (old_size = 0; old_size < UTF8_SIZE; old_size++) { | 	if (grid_utf8_append(gu, utf8data) != 0) { | ||||||
| 		if (gu->data[old_size] == 0xff) | 		/* Failed: scrap this character and replace with underscores. */ | ||||||
| 			break; | 		if (gu->width == 1) { | ||||||
| 	} | 			gc->data = '_'; | ||||||
|  | 			gc->flags &= ~GRID_FLAG_UTF8; | ||||||
| 	/* If there isn't space, scrap this character. */ | 		} else { | ||||||
| 	if (old_size + utf8data->size > UTF8_SIZE) { | 			for (i = 0; i < gu->width && i != sizeof gu->data; i++) | ||||||
| 		for (i = 0; i < gu->width && i != UTF8_SIZE; i++) |  | ||||||
| 				gu->data[i] = '_'; | 				gu->data[i] = '_'; | ||||||
| 		if (i != UTF8_SIZE) | 			if (i != sizeof gu->data) | ||||||
| 				gu->data[i] = 0xff; | 				gu->data[i] = 0xff; | ||||||
| 			gu->width = i; | 			gu->width = i; | ||||||
| 		return (0); | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	/* Otherwise save the character. */ |  | ||||||
| 	memcpy(gu->data + old_size, utf8data->data, utf8data->size); |  | ||||||
| 	if (old_size + utf8data->size != UTF8_SIZE) |  | ||||||
| 		gu->data[old_size + utf8data->size] = 0xff; |  | ||||||
| 	return (0); | 	return (0); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										14
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -74,6 +74,12 @@ extern char   **environ; | |||||||
| #define PRINT_LENGTH 512	/* printed error/message size */ | #define PRINT_LENGTH 512	/* printed error/message size */ | ||||||
| #define ENVIRON_LENGTH 1024	/* environment variable length */ | #define ENVIRON_LENGTH 1024	/* environment variable length */ | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * UTF-8 data size. This must be big enough to hold combined characters as well | ||||||
|  |  * as single. | ||||||
|  |  */ | ||||||
|  | #define UTF8_SIZE 9 | ||||||
|  |  | ||||||
| /* Fatal errors. */ | /* Fatal errors. */ | ||||||
| #define fatal(msg) log_fatal("%s: %s", __func__, msg); | #define fatal(msg) log_fatal("%s: %s", __func__, msg); | ||||||
| #define fatalx(msg) log_fatalx("%s: %s", __func__, msg); | #define fatalx(msg) log_fatalx("%s: %s", __func__, msg); | ||||||
| @@ -531,7 +537,6 @@ struct mode_key_table { | |||||||
|  * reinject stored UTF-8 data back into screen_write_cell after combining (ugh |  * reinject stored UTF-8 data back into screen_write_cell after combining (ugh | ||||||
|  * XXX XXX). |  * XXX XXX). | ||||||
|  */ |  */ | ||||||
| #define UTF8_SIZE 9 |  | ||||||
| struct utf8_data { | struct utf8_data { | ||||||
| 	u_char	data[UTF8_SIZE]; | 	u_char	data[UTF8_SIZE]; | ||||||
|  |  | ||||||
| @@ -1675,6 +1680,13 @@ char	*grid_string_cells(struct grid *, u_int, u_int, u_int); | |||||||
| void	 grid_duplicate_lines( | void	 grid_duplicate_lines( | ||||||
|     	     struct grid *, u_int, struct grid *, u_int, u_int); |     	     struct grid *, u_int, struct grid *, u_int, u_int); | ||||||
|  |  | ||||||
|  | /* grid-utf8.c */ | ||||||
|  | size_t	 grid_utf8_size(const struct grid_utf8 *); | ||||||
|  | size_t	 grid_utf8_copy(const struct grid_utf8 *, char *, size_t); | ||||||
|  | void	 grid_utf8_set(struct grid_utf8 *, const struct utf8_data *); | ||||||
|  | int	 grid_utf8_append(struct grid_utf8 *, const struct utf8_data *); | ||||||
|  | int	 grid_utf8_compare(const struct grid_utf8 *, const struct grid_utf8 *); | ||||||
|  |  | ||||||
| /* grid-view.c */ | /* grid-view.c */ | ||||||
| const struct grid_cell *grid_view_peek_cell(struct grid *, u_int, u_int); | const struct grid_cell *grid_view_peek_cell(struct grid *, u_int, u_int); | ||||||
| struct grid_cell *grid_view_get_cell(struct grid *, u_int, u_int); | struct grid_cell *grid_view_get_cell(struct grid *, u_int, u_int); | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								tty.c
									
									
									
									
									
								
							| @@ -365,16 +365,12 @@ tty_putc(struct tty *tty, u_char ch) | |||||||
| void | void | ||||||
| tty_pututf8(struct tty *tty, const struct grid_utf8 *gu) | tty_pututf8(struct tty *tty, const struct grid_utf8 *gu) | ||||||
| { | { | ||||||
| 	u_int	i; | 	size_t	size; | ||||||
|  |  | ||||||
| 	for (i = 0; i < UTF8_SIZE; i++) { | 	size = grid_utf8_size(gu); | ||||||
| 		if (gu->data[i] == 0xff) | 	bufferevent_write(tty->event, gu->data, size); | ||||||
| 			break; |  | ||||||
| 		bufferevent_write(tty->event, &gu->data[i], 1); |  | ||||||
| 	if (tty->log_fd != -1) | 	if (tty->log_fd != -1) | ||||||
| 			write(tty->log_fd, &gu->data[i], 1); | 		write(tty->log_fd, gu->data, size); | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	tty->cx += gu->width; | 	tty->cx += gu->width; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -486,6 +486,7 @@ window_copy_search_compare( | |||||||
| { | { | ||||||
| 	const struct grid_cell	*gc, *sgc; | 	const struct grid_cell	*gc, *sgc; | ||||||
| 	const struct grid_utf8	*gu, *sgu; | 	const struct grid_utf8	*gu, *sgu; | ||||||
|  | 	size_t			 size; | ||||||
|  |  | ||||||
| 	gc = grid_peek_cell(gd, px, py); | 	gc = grid_peek_cell(gd, px, py); | ||||||
| 	sgc = grid_peek_cell(sgd, spx, 0); | 	sgc = grid_peek_cell(sgd, spx, 0); | ||||||
| @@ -496,7 +497,7 @@ window_copy_search_compare( | |||||||
| 	if (gc->flags & GRID_FLAG_UTF8) { | 	if (gc->flags & GRID_FLAG_UTF8) { | ||||||
| 		gu = grid_peek_utf8(gd, px, py); | 		gu = grid_peek_utf8(gd, px, py); | ||||||
| 		sgu = grid_peek_utf8(sgd, spx, 0); | 		sgu = grid_peek_utf8(sgd, spx, 0); | ||||||
| 		if (memcmp(gu->data, sgu->data, UTF8_SIZE) == 0) | 		if (grid_utf8_compare(gu, sgu)) | ||||||
| 			return (1); | 			return (1); | ||||||
| 	} else { | 	} else { | ||||||
| 		if (gc->data == sgc->data) | 		if (gc->data == sgc->data) | ||||||
| @@ -895,7 +896,8 @@ window_copy_copy_line(struct window_pane *wp, | |||||||
|  	const struct grid_cell	*gc; |  	const struct grid_cell	*gc; | ||||||
|  	const struct grid_utf8	*gu; |  	const struct grid_utf8	*gu; | ||||||
| 	struct grid_line	*gl; | 	struct grid_line	*gl; | ||||||
| 	u_int			 i, j, xx, wrapped = 0; | 	u_int			 i, xx, wrapped = 0; | ||||||
|  | 	size_t			 size; | ||||||
|  |  | ||||||
| 	if (sx > ex) | 	if (sx > ex) | ||||||
| 		return; | 		return; | ||||||
| @@ -928,12 +930,9 @@ window_copy_copy_line(struct window_pane *wp, | |||||||
| 				(*buf)[(*off)++] = gc->data; | 				(*buf)[(*off)++] = gc->data; | ||||||
| 			} else { | 			} else { | ||||||
| 				gu = grid_peek_utf8(gd, i, sy); | 				gu = grid_peek_utf8(gd, i, sy); | ||||||
| 				*buf = xrealloc(*buf, 1, (*off) + UTF8_SIZE); | 				size = grid_utf8_size(gu); | ||||||
| 				for (j = 0; j < UTF8_SIZE; j++) { | 				*buf = xrealloc(*buf, 1, (*off) + size); | ||||||
| 					if (gu->data[j] == 0xff) | 				*off += grid_utf8_copy(gu, *buf + *off, size); | ||||||
| 						break; |  | ||||||
| 					(*buf)[(*off)++] = gu->data[j]; |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Nicholas Marriott
					Nicholas Marriott