[Commit] jove abbrev.c,1.2,1.3 ask.c,1.2,1.3 buf.c,1.2,1.3 c.c,1.3,1.4 case.c,1.2,1.3 ctype.h,1.1.1.1,1.2 delete.c,1.1.1.1,1.2 disp.c,1.2,1.3 error.c,1.1.1.1,1.2 fp.c,1.3,1.4 funcdefs.c,1.1.1.1,1.2 insert.c,1.2,1.3 io.c,1.3,1.4 io.h,1.1.1.1,1.2 iproc.c,1.2,1.3 jove.c,1.3,1.4 jove.h,1.4,1.5 keymaps.txt,1.1.1.1,1.2 misc.c,1.2,1.3 move.c,1.1.1.1,1.2 paragraph.c,1.3,1.4 portsrv.c,1.1.1.1,1.2 proc.c,1.1.1.1,1.2 re1.c,1.2,1.3 recover.c,1.3,1.4 scandir.c,1.1.1.1,1.2 screen.c,1.2,1.3 temp.h,1.1.1.1,1.2 term.c,1.3,1.4 tune.h,1.3,1.4 util.c,1.2,1.3 vars.c,1.1.1.1,1.2

Keith Packard commit@keithp.com
Wed, 14 May 2003 17:01:10 -0700


Committed by: keithp

Update of /local/src/CVS/jove
In directory home.keithp.com:/tmp/cvs-serv8425

Modified Files:
	abbrev.c ask.c buf.c c.c case.c ctype.h delete.c disp.c 
	error.c fp.c funcdefs.c insert.c io.c io.h iproc.c jove.c 
	jove.h keymaps.txt misc.c move.c paragraph.c portsrv.c proc.c 
	re1.c recover.c scandir.c screen.c temp.h term.c tune.h util.c 
	vars.c 
Log Message:
Switch to UTF-8 for internal storage and file format.  Permit Latin-1 output

Index: abbrev.c
===================================================================
RCS file: /local/src/CVS/jove/abbrev.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- abbrev.c	11 Jul 2001 06:42:26 -0000	1.2
+++ abbrev.c	15 May 2003 00:01:06 -0000	1.3
@@ -96,16 +96,16 @@
 {
 	Bufpos	point;
 	char	wordbuf[1024];
-	register char	*wp = wordbuf,
-			*cp;
-	register int	c;
+	char	*wp = wordbuf,
+		*cp;
+	int	c;
 	int	UC_count = 0;
 	struct abbrev	*ap;
 
 	DOTsave(&point);
     WITH_TABLE(curbuf->b_major)
 	b_word(1);
-	while (curchar < point.p_char && ismword(c = linebuf[curchar])) {
+	while (curchar < point.p_char && ismword(cur_char())) {
 		if (AutoCaseAbbrev) {
 			if (isupper(c)) {
 				UC_count++;
@@ -114,8 +114,8 @@
 		}
 		if (wp >= wordbuf + (sizeof (wordbuf) - 1))
 			break;
-		*wp++ = c;
-		curchar++;
+		wp = unparse_ucs4 (c, wp);
+		right_char ();
 	}
 	*wp = '\0';
     END_TABLE();
@@ -127,14 +127,14 @@
 	}
 	del_char(BACKWARD, (wp - wordbuf));
 
-	for (cp = ap->a_phrase; c = *cp; ) {
+	for (cp = ap->a_phrase; c = parse_ucs4(cp); ) {
 		if (AutoCaseAbbrev) {
 			insert_c(islower(c) && UC_count &&
 			       (cp == ap->a_phrase || (UC_count > 1 && (cp[-1] == ' '))) ?
 				toupper(c) : c, 1);
 		} else
 			insert_c(c, 1);
-		cp += 1;
+		cp = buf_next (cp);
 	}
 
 	if (ap->a_cmdhook != 0)
@@ -283,4 +283,4 @@
 	ap->a_cmdhook = hook;
 }
 
-#endif ABBREV
+#endif /* ABBREV */

Index: ask.c
===================================================================
RCS file: /local/src/CVS/jove/ask.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ask.c	11 Jul 2001 06:42:26 -0000	1.2
+++ ask.c	15 May 2003 00:01:06 -0000	1.3
@@ -401,8 +401,8 @@
 		makedirty(curline);
 	}
 	is_ntdir = ((numfound == 1) &&
-		    (curchar > 0) &&
-		    (linebuf[curchar - 1] != '/') &&
+		    (!bolp()) &&
+		    (prev_char () != '/') &&
 		    (isdir(linebuf)));
 	if (the_same && !is_ntdir) {
 		add_mess((n == 1) ? " [Unique]" : " [Ambiguous]");

Index: buf.c
===================================================================
RCS file: /local/src/CVS/jove/buf.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- buf.c	11 Jul 2001 06:42:26 -0000	1.2
+++ buf.c	15 May 2003 00:01:06 -0000	1.3
@@ -740,6 +740,103 @@
 	return b;
 }
 
+ucs4 parse_ucs4 (char *buf)
+{
+	ucs4    result = (*buf++ & 0xff);
+
+	if ((result & 0xc0) == 0xc0)
+	{
+		ucs4	mask = 0x20;
+		int	extra = 1;
+
+		while ((result & mask) != 0)
+		{
+			extra++;
+			mask >>= 1;
+		}
+		result &= (mask - 1);
+		while (extra-- > 0)
+		{
+			ucs4 c = *buf++;
+
+			if (!(c & 0x80))
+				break;
+			result = (result << 6) | (c & 0x3f);
+		}
+	}
+	return result;
+}
+
+char *unparse_ucs4 (ucs4 c, char *buf)
+{
+	char	d;
+	int	bits;
+
+	     if (c <       0x80) { d = c;                         bits= -6; }
+	else if (c <      0x800) { d= ((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
+	else if (c <    0x10000) { d= ((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
+	else if (c <   0x200000) { d= ((c >> 18) & 0x07) | 0xF0;  bits= 12; }
+	else if (c <  0x4000000) { d= ((c >> 24) & 0x03) | 0xF8;  bits= 18; }
+	else if (c < 0x80000000) { d= ((c >> 30) & 0x01) | 0xFC;  bits= 24; }
+	else                     { d = c;                         bits= -6; }
+
+	*buf++ = d;
+
+	for ( ; bits >= 0; bits-= 6)
+		*buf++ = ((c >> bits) & 0x3F) | 0x80;
+	return buf;
+}
+
+ucs4 next_ucs4(char **bufp)
+{
+    char    *buf = *bufp;
+    ucs4    result = *buf++ & 0xff;
+
+    if ((result & 0xc0) == 0xc0)
+    {
+	int	extra = 1;
+	ucs4	mask = 0x20;
+
+	while ((result & mask))
+	{
+	    extra++;
+	    mask >>= 1;
+	}
+	result &= (mask - 1);
+	while (extra--)
+	{
+	    ucs4	c = *buf & 0xff;
+	    if ((c & 0xc0) != 0x80)
+		break;
+	    result = (result << 6) | (c & 0x3f);
+	    buf++;
+	}
+    }
+    *bufp = buf;
+    return result;
+}
+
+char *buf_next (char *buf)
+{
+	if ((*buf++ & 0xc0) == 0xc0)
+		while ((*buf & 0xc0) == 0x80)
+			buf++;
+	return buf;
+}
+
+char *buf_prev (char *buf, char *first)
+{
+	if ((*--buf & 0xc0) == 0x80)
+	{
+		char	*prev = buf;
+		while (prev > first && (*prev & 0xc0) == 0x80)
+			prev--;
+		if ((*prev & 0xc0) == 0xc0)
+			buf = prev;
+	}
+	return buf;
+}
+
 /* set alternate buffer */
 
 SetABuf(b)

Index: c.c
===================================================================
RCS file: /local/src/CVS/jove/c.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- c.c	26 Jul 2002 19:58:40 -0000	1.3
+++ c.c	15 May 2003 00:01:06 -0000	1.4
@@ -88,13 +88,13 @@
 	char	re_buf[V_STRING_LEN],
 		*re_alts[NALTS];
 	int	count = 0;
-	register char	*lp,
-			c;
-	char	p_match,
-		re_str[V_STRING_LEN],
-		*cp,
-		quote_c = 0;
-	register int	c_char;
+	char	*lp;
+	ucs4	c;
+	ucs4	p_match;
+	char	re_str[V_STRING_LEN],
+		*cp;
+	ucs4	quote_c = 0;
+	int	c_char;
 	Line	*comment_line = 0;
 	int	comment_cchar;
 	int	in_comment = COMMENT_NONE,
@@ -125,11 +125,11 @@
 		curchar = sp->p_char;	/* here's where I cheat */
 		c_char = curchar;
 		if (dir == FORWARD)
-			c_char--;
+			c_char = buf_prev (lp + c_char, lp) - lp;
 
 		if (backslashed(lp, c_char))
 			continue;
-		c = lp[c_char];
+		c = parse_ucs4 (lp + c_char);
 		/* check if this is a comment (if we're not inside quotes) */
 		if (quote_c == 0) {
 		    if (in_comment == COMMENT_NONE)
@@ -138,32 +138,15 @@
 			{
 			    if (c == '/')
 			    {
-				if (lp[c_char+1] == '*')
+				if (parse_ucs4 (buf_next (lp+c_char)) == '*')
 				    in_comment = COMMENT_C;
-#if 0
-				else if (lp[c_char+1] == '/')
-				{
-				    in_comment = COMMENT_CPP;
-				    comment_line = curline;
-				    comment_cchar = c_char;
-				}
-#endif
 			    }
 			} else {
 			    int	i;
 
-#if 0
-			    for (i = 0; i < c_char; i++)
-				if (lp[i] == '/' && lp[i+1] == '/')
-				{
-				    in_comment = COMMENT_CPP;
-				    comment_line = curline;
-				    comment_cchar = i;
-				    break;
-				}
-#endif
 			    if (in_comment == COMMENT_NONE)
-				if (c == '/' && c_char != 0 && lp[c_char-1] == '*')
+				if (c == '/' && c_char != 0 && 
+				    parse_ucs4 (buf_prev(lp+c_char, lp)) == '*')
 				    in_comment = COMMENT_C;
 			}
 		    }
@@ -188,13 +171,13 @@
 			{
 			    if (dir == FORWARD)
 			    {
-				if (c_char != 0 && lp[c_char - 1] == '*')
+				if (c_char != 0 && parse_ucs4 (buf_prev(lp+c_char, lp)) == '*')
 				    in_comment = COMMENT_NONE;
 			    }
 			    else
 			    {
-				if (lp[c_char+1] == '*')
-				    in_comment = COMMENT_NONE;
+				if (parse_ucs4 (buf_next (lp+c_char)) == '*')
+					in_comment = COMMENT_NONE;
 			    }
 			}
 		    }
@@ -251,12 +234,12 @@
 do_expr(dir, skip_words)
 register int	dir;
 {
-	register char	c,
+	register ucs4	c,
 			syntax = (dir == FORWARD) ? _Op : _Cl;
 
 	if (dir == BACKWARD)
 		b_char(1);
-	c = linebuf[curchar];
+	c = cur_char ();
 	for (;;) {
 		if (!skip_words && ismword(c)) {
 		    WITH_TABLE(curbuf->b_major)
@@ -270,7 +253,7 @@
 		f_char(dir);
 		if (eobp() || bobp())
 			return;
-		c = linebuf[curchar];
+		c = cur_char ();
 	}
 }
 
@@ -364,7 +347,7 @@
 FindMatch(int dir)
 {
 	register Bufpos	*bp;
-	register char	c = linebuf[curchar];
+	register ucs4	c = cur_char ();
 
 	if ((index(p_types, c) == 0) ||
 	    (backslashed(linebuf, curchar)))
@@ -415,7 +398,7 @@
 	}
 	while (num > 0) {
 		if (curchar - offset >= 0 && 
-		    iswhite (linebuf[curchar-offset]) &&
+		    iswhite (parse_ucs4 (linebuf+(curchar-offset))) &&
 		    ((((curpos = calc_pos (linebuf, curchar)) + extrapos)
 		      % CIndIncrmt) == 0) || dir != BACKWARD) 
 		{
@@ -432,9 +415,12 @@
 			
 			tempchar = curchar;
 			while (COMPAREPOS && 
-			       iswhite ((c = linebuf[tempchar-offset])))
+			       iswhite ((c = parse_ucs4 (linebuf+(tempchar-offset)))))
 			{
-				tempchar += step;
+				if (step > 0)
+					tempchar = buf_next(linebuf+tempchar)-linebuf;
+				else
+					tempchar = buf_prev(linebuf+tempchar,linebuf)-linebuf;
 				curpos += step;
 				if (c == '\t')
 					curpos = calc_pos (linebuf, tempchar);
@@ -467,9 +453,10 @@
 		lremove(before.p_line, after.p_line);
 	}
 	if (extrapos) {
+		int	oldpos = curchar;
 		insert_c(' ', abs (extrapos));
 		if (extrapos < 0)
-			curchar += extrapos;
+			curchar = oldpos;
 	}
 	return YES;
 }
@@ -484,11 +471,11 @@
 	/* be fancy - make it line up with the start of this
 	   statement if it crosses lines */
 	Eol ();
-	while (linebuf[curchar] != ')')
+	while (cur_char () != ')')
 	{
-		if (curchar <= 0)
+		if (bolp() <= 0)
 			return NO;
-		curchar--;
+		left_char ();
 	}
 	bp = m_paren (')', BACKWARD, NO, YES);
 	if (bp && bp->p_line != curline) {
@@ -535,14 +522,14 @@
     int		indent;
     int		incrmt = 0;
     int		fromIndent;
-    int		c;
+    ucs4	c;
     int		mp_save;
     
     DOTsave (&save);
     ToIndent ();
     fromIndent = save.p_char - curchar;
     
-    c = linebuf[curchar];
+    c = cur_char ();
     
     bp = 0;
     if (c == '#')
@@ -872,27 +859,28 @@
 	LineInsert(1);
 	DelWtSpace();
 	Bol();
-	for (cp = open_c; *cp; cp++) {
-		if (*cp == '\r') {
+	for (cp = open_c; *cp; cp = buf_next (cp)) {
+		ucs4	c = parse_ucs4(cp);
+		if (c == '\r') {
 			if (!eolp())
 				LineInsert(1);
 			else
 				line_move(FORWARD, 1, NO);
-		} else if (*cp == ' ' || *cp == '\t') {
-			if (linebuf[curchar] != *cp)
-				insert_c(*cp, 1);
+		} else if (c == ' ' || c == '\t') {
+			if (cur_char() != *cp)
+				insert_c(c, 1);
 		} else
 			/* Since we matched the open comment string on this
 			   line, we don't need to worry about crossing line
 			   boundaries. */
-			curchar++;
+			right_char ();
 	}
 	savedot = MakeMark(curline, curchar, M_FLOATER);
 
 	/* We need to strip the line header pattern of leading white space
 	   since we need to match the line after all of its leading
 	   whitespace is gone. */
-	for (cp = l_header; *cp && (isspace(*cp)); cp++)
+	for (cp = l_header; *cp && (isspace(parse_ucs4 (cp))); cp = buf_next(cp))
 		;
 	header_len = strlen(cp);
 	trailer_len = strlen(l_trailer);
@@ -968,5 +956,5 @@
 	del_char(FORWARD, 1);
 }
 
-#endif CMT_FMT
+#endif /* CMT_FMT */
 

Index: case.c
===================================================================
RCS file: /local/src/CVS/jove/case.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- case.c	11 Jul 2001 06:42:26 -0000	1.2
+++ case.c	15 May 2003 00:01:06 -0000	1.3
@@ -34,12 +34,7 @@
 			modify();
 			makedirty(curline);
 		}
-		if (eolp()) {
-			if (curline->l_next == 0)
-				break;
-			SetLine(curline->l_next);
-		} else
-			curchar++;
+		f_char (1);
 	}
 	if (restore)
 		SetDot(&b);
@@ -68,13 +63,13 @@
 			modify();
 			makedirty(curline);
 		}
-		curchar++;
-		while (!eolp() && isword(linebuf[curchar])) {
+		right_char ();
+		while (!eolp() && isword(cur_char ())) {
 			if (lower(&linebuf[curchar])) {
 				modify();
 				makedirty(curline);
 			}
-			curchar++;
+			right_char ();
 		}
 	}
 	if (restore)

Index: ctype.h
===================================================================
RCS file: /local/src/CVS/jove/ctype.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- ctype.h	10 Mar 2001 12:23:12 -0000	1.1.1.1
+++ ctype.h	15 May 2003 00:01:06 -0000	1.2
@@ -17,21 +17,22 @@
 #define _Cl	0200
 
 extern int	SyntaxTable;
+#define islatin1(c)	((unsigned) (c) < 0x100)
 #define iswhite(c)	(isspace(c))
-#define isword(c)	((CharTable[SyntaxTable])[((int) c) & 0377]&(_W))
-#define	isalpha(c)	((CharTable[SyntaxTable])[((int) c) & 0377]&(_U|_L))
-#define	isupper(c)	((CharTable[SyntaxTable])[((int) c) & 0377]&_U)
-#define	islower(c)	((CharTable[SyntaxTable])[((int) c) & 0377]&_L)
-#define	isdigit(c)	((CharTable[SyntaxTable])[((int) c) & 0377]&_N)
+#define isword(c)	(islatin1(c) && (CharTable[SyntaxTable])[((int) c) & 0377]&(_W))
+#define	isalpha(c)	(islatin1(c) && (CharTable[SyntaxTable])[((int) c) & 0377]&(_U|_L))
+#define	isupper(c)	(islatin1(c) && (CharTable[SyntaxTable])[((int) c) & 0377]&_U)
+#define	islower(c)	(islatin1(c) && (CharTable[SyntaxTable])[((int) c) & 0377]&_L)
+#define	isdigit(c)	(islatin1(c) && (CharTable[SyntaxTable])[((int) c) & 0377]&_N)
 #define	isspace(c)	(c == ' ' || c == '\t')
-#define ispunct(c)	((CharTable[SyntaxTable])[((int) c) & 0377]&_P)
+#define ispunct(c)	(islatin1(c) && (CharTable[SyntaxTable])[((int) c) & 0377]&_P)
 #define toupper(c)	((c)&~040)
 #define tolower(c)	((c)|040)
 #define toascii(c)	((c)&0377)
-#define isctrl(c)	((CharTable[0][((int) c) & 0377])&_C)
-#define isopenp(c)	((CharTable[0][((int) c) & 0377])&_Op)
-#define isclosep(c)	((CharTable[0][((int) c) & 0377])&_Cl)
-#define has_syntax(c,s)	((CharTable[SyntaxTable][((int) c) & 0377])&s)
+#define isctrl(c)	(islatin1(c) && (CharTable[0][((int) c) & 0377])&_C)
+#define isopenp(c)	(islatin1(c) && (CharTable[0][((int) c) & 0377])&_Op)
+#define isclosep(c)	(islatin1(c) && (CharTable[0][((int) c) & 0377])&_Cl)
+#define has_syntax(c,s)	(islatin1(c) && (CharTable[SyntaxTable][((int) c) & 0377])&s)
 #define WITH_TABLE(x) \
 { \
 	int	push = SyntaxTable; \

Index: delete.c
===================================================================
RCS file: /local/src/CVS/jove/delete.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- delete.c	10 Mar 2001 12:23:11 -0000	1.1.1.1
+++ delete.c	15 May 2003 00:01:06 -0000	1.2
@@ -107,9 +107,12 @@
 DelPChar()
 {
 	if (MinorMode(OverWrite)) {
-		int	count = min(arg_value(), curchar);
+		int	count = arg_value();
+		int	i;
 
-		b_char(count);
+		for (i = 0; i < count && !bolp(); i++)
+			b_char(1);
+		count = i;
 
 		/* overwrite with spaces */
 		set_arg_value(count);
@@ -238,13 +241,16 @@
 
 DelWtSpace()
 {
-	register char	*ep = &linebuf[curchar],
-			*sp = &linebuf[curchar];
+	char	*ep = &linebuf[curchar],
+		*sp = &linebuf[curchar], *pp;
+	ucs4	c;
+	
 
-	while (*ep == ' ' || *ep == '\t')
-		ep++;
-	while (sp > linebuf && *(sp - 1) == ' ' || *(sp - 1) == '\t')
-		sp--;
+	while ((c = parse_ucs4 (ep)) == ' ' || c == '\t')
+		ep = buf_next (ep);
+	while ((pp = buf_prev (sp, linebuf)) != sp &&
+	       (c = parse_ucs4 (pp)) == ' ' || c == '\t')
+		sp = pp;
 	if (sp != ep) {
 		curchar = sp - linebuf;
 		DFixMarks(curline, curchar, curline, curchar + (ep - sp));
@@ -265,7 +271,7 @@
 	register Mark	*dot;
 	int	all;
 
-	if (!blnkp(&linebuf[curchar]))
+	if (!blnkp(cur_char ()))
 		return;
 	dot = MakeMark(curline, curchar, M_FLOATER);
 	all = !blnkp(linebuf);

Index: disp.c
===================================================================
RCS file: /local/src/CVS/jove/disp.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- disp.c	11 Jul 2001 06:42:26 -0000	1.2
+++ disp.c	15 May 2003 00:01:06 -0000	1.3
@@ -152,14 +152,14 @@
 	return calc_pos(lcontents(line), c_char);
 }
 
-calc_pos(lp, c_char)
-register char	*lp;
-register int	c_char;
+int
+calc_pos(char *lp, int c_char)
 {
-	register int	pos = 0;
-	register int	c;
+	int	pos = 0;
+	ucs4	c;
+	char	*ep = lp + c_char;
 
-	while ((--c_char >= 0) && (c = *lp++) != 0) {
+	while (lp < ep && (c = next_ucs4 (&lp))) {
 		if (c == '\t')
 			pos += (tabstop - (pos % tabstop));
 		else if (isctrl(c))
@@ -515,7 +515,7 @@
 			else
 				PhysScreen[linenum].s_id = -1;
 		} else
-#endif ID_CHAR
+#endif /* ID_CHAR */
 		    if (BufSwrite(linenum))
 			do_cl_eol(linenum);
 		else
@@ -574,20 +574,18 @@
 }
 
 /* private*/
-DeTab(s_offset, buf, outbuf, limit, visspace)
-register char	*buf;
-char	*outbuf;
+DeTab(int s_offset, char *buf, ucs4 *outbuf, int limit, int visspace)
 {
-	register char	*phys_p = outbuf,
+	register ucs4	*phys_p = outbuf,
 			c;
 	register int	pos = 0;
-	char		*limitp = &outbuf[limit];
+	ucs4		*limitp = &outbuf[limit];
 
 #define OkayOut(ch)	if ((pos++ >= s_offset) && (phys_p < limitp))\
 				*phys_p++ = ch;\
 			else
 
-	while (c = *buf++) {
+	while (c = next_ucs4(&buf)) {
 		if (c == '\t') {
 			int	nchars = (tabstop - (pos % tabstop));
 
@@ -621,8 +619,7 @@
   	Returns Non-Zero if you are finished (no differences left). */
 
 /*private*/
-IDchar(new, lineno, col)
-register char	*new;
+IDchar(ucs4 *new, int lineno, int col)
 {
 	register int	i;
 	int	j,
@@ -810,7 +807,7 @@
 		CapCol = CO - 1;
 }
 
-#endif ID_CHAR
+#endif /* ID_CHAR */
 
 /* chkmail() returns nonzero if there is new mail since the
    last time we checked. */

Index: error.c
===================================================================
RCS file: /local/src/CVS/jove/error.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- error.c	10 Mar 2001 12:23:11 -0000	1.1.1.1
+++ error.c	15 May 2003 00:01:06 -0000	1.2
@@ -294,4 +294,4 @@
 	SetBuf(buftospel);
 }
 
-#endif SPELL
+#endif /* SPELL */

Index: fp.c
===================================================================
RCS file: /local/src/CVS/jove/fp.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- fp.c	20 Feb 2002 20:34:31 -0000	1.3
+++ fp.c	15 May 2003 00:01:06 -0000	1.4
@@ -31,7 +31,41 @@
 	termflush(EOF);
 }
 
-termflush(c)
+int Utf8Out = 0;
+
+void
+termoutchar (ucs4 c)
+{
+    char	d;
+    int	bits;
+
+    if (!Utf8Out)
+    {
+	bits = -6;
+	if (c < 0x100)
+	    d = c;
+	else
+	    d = '';
+    }
+    else
+    {
+	     if (c <       0x80) { d = c;                         bits= -6; }
+	else if (c <      0x800) { d= ((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
+	else if (c <    0x10000) { d= ((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
+	else if (c <   0x200000) { d= ((c >> 18) & 0x07) | 0xF0;  bits= 12; }
+	else if (c <  0x4000000) { d= ((c >> 24) & 0x03) | 0xF8;  bits= 18; }
+	else if (c < 0x80000000) { d= ((c >> 30) & 0x01) | 0xFC;  bits= 24; }
+	else                     { d = c;                         bits= -6; }
+    }
+
+    termoutbyte (d);
+
+    for ( ; bits >= 0; bits-= 6)
+	termoutbyte (((c >> bits) & 0x3F) | 0x80);
+}
+
+void
+termflush(char c)
 {
 	register int	n;
 

Index: funcdefs.c
===================================================================
RCS file: /local/src/CVS/jove/funcdefs.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- funcdefs.c	10 Mar 2001 12:23:11 -0000	1.1.1.1
+++ funcdefs.c	15 May 2003 00:01:06 -0000	1.2
@@ -155,6 +155,7 @@
 	Tab(),
 	DescribeCompose(),
 	HandleCompose(),
+	HandleUnicode(),
 	DoParen(),
 	DoOpenBrace(),
 	ParseAll(),
@@ -283,11 +284,11 @@
 
 #	define WIRED_CMD(c)	c
 
-#else TXT_TO_C
+#else /* TXT_TO_C */
 
 #	define WIRED_CMD(c)	0
 
-#endif TXT_TO_C
+#endif /* TXT_TO_C */
 
 struct cmd	commands[] = {
 	FUNCTION, "Prefix-1", WIRED_CMD(EscPrefix),
@@ -400,7 +401,7 @@
 	FUNCTION, "exit-jove", WIRED_CMD(Leave),
 #ifdef CMT_FMT
  	FUNCMOD, "fill-comment", WIRED_CMD(Comment),
-#endif CMT_FMT
+#endif /* CMT_FMT */
 	FUNCMOD, "fill-paragraph", WIRED_CMD(Justify),
 	FUNCMOD, "fill-region", WIRED_CMD(RegJustify),
 	FUNCMOD, "filter-buffer", WIRED_CMD(FilterBuffer),
@@ -430,6 +431,7 @@
 	FUNCTION, "highlight-current-line", WIRED_CMD(WHighCur),
 	FUNCINS, "handle-compose", WIRED_CMD(HandleCompose),
 	FUNCINS, "handle-tab", WIRED_CMD(Tab),
+	FUNCINS, "handle-unicode", WIRED_CMD(HandleUnicode),
 	FUNCTION, "i-search-forward", WIRED_CMD(IncFSearch),
 	FUNCTION, "i-search-reverse", WIRED_CMD(IncRSearch),
 	FUNCMOD, "indent-line", WIRED_CMD(IndentLine),

Index: insert.c
===================================================================
RCS file: /local/src/CVS/jove/insert.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- insert.c	11 Jul 2001 06:42:26 -0000	1.2
+++ insert.c	15 May 2003 00:01:06 -0000	1.3
@@ -1,5 +1,5 @@
 /************************************************************************
- * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
+ * This program is Copyright © 1986 by Jonathan Payne.  JOVE is         *
  * provided to you without charge, and with no warranty.  You may give  *
  * away copies of JOVE, including sources, provided that this notice is *
  * included in all the files.                                           *
@@ -58,7 +58,7 @@
 	}
 
 	modify();
-	if (curchar != 0) {
+	if (!bolp()) {
 		strcpy(new_line, &linebuf[curchar]);
 		linebuf[curchar] = '\0';	/* Shorten this line */
 		SavLine(curline, linebuf);
@@ -77,15 +77,17 @@
 
 /* Replaces white space before dot to make dot reach goal */
  
-n_tab(goal)
-register int	goal;
+void
+n_tab(int goal)
 {
 	int	incrmt, dotcol;
-	register char	*sp, *ep;
+	char	*sp, *ep, *pp;
+	ucs4	c;
 	
 	sp = ep = &linebuf[curchar];
-	while (sp > linebuf && *(sp - 1) == ' ' || *(sp - 1) == '\t')
-		sp--;
+	while ((pp = buf_prev (sp, linebuf)) >= linebuf &&
+	       (c = parse_ucs4 (pp)) == ' ' || c == '\t')
+		sp = pp;
 	if (sp != ep) {
 		curchar = sp - linebuf;
 		DFixMarks(curline, curchar, curline, curchar + (ep - sp));
@@ -137,7 +139,7 @@
 {
 #ifdef ABBREV
 	if (MinorMode(Abbrev) && !ismword(LastKeyStruck) &&
-	    !bolp() && ismword(linebuf[curchar - 1]))
+	    !bolp() && ismword(prev_char ()))
 		AbbrevExpand();
 #endif
 	if (MinorMode(OverWrite)) {
@@ -148,7 +150,7 @@
 			int	pos = calc_pos(linebuf, curchar);
 
 			if (!eolp()) {
-				if (linebuf[curchar] == '\t') {
+				if (cur_char () == '\t') {
 					if ((pos + 1) == ((pos + tabstop) - (pos % tabstop)))
 						del_char(FORWARD, 1);
 				} else
@@ -168,16 +170,45 @@
 	insert_c(c, arg_value());
 }
 
+/* insert ucs4 character C at point */
+static void
+insert_ucs4 (ucs4 c)
+{
+	char	d;
+	int	bits;
+	int	s = curchar;
+
+	     if (c <       0x80) { d = c;                         bits= -6; }
+	else if (c <      0x800) { d= ((c >>  6) & 0x1F) | 0xC0;  bits=  0; }
+	else if (c <    0x10000) { d= ((c >> 12) & 0x0F) | 0xE0;  bits=  6; }
+	else if (c <   0x200000) { d= ((c >> 18) & 0x07) | 0xF0;  bits= 12; }
+	else if (c <  0x4000000) { d= ((c >> 24) & 0x03) | 0xF8;  bits= 18; }
+	else if (c < 0x80000000) { d= ((c >> 30) & 0x01) | 0xFC;  bits= 24; }
+	else d = c;
+
+	ins_c (d, linebuf, curchar, 1, LBSIZE);
+	curchar++;
+
+	for ( ; bits >= 0; bits-= 6)
+	{
+		ins_c ((((c >> bits) & 0x3F) | 0x80), linebuf, curchar, 1, LBSIZE);
+		curchar++;
+	}
+}
+
 /* insert character C N times at point */
-insert_c(c, n)
+void
+insert_c(ucs4 c, int n)
 {
+	int	s = curchar;
+	
 	if (n <= 0)
 		return;
 	modify();
 	makedirty(curline);
-	ins_c(c, linebuf, curchar, n, LBSIZE);
-	IFixMarks(curline, curchar, curline, curchar + n);
-	curchar += n;
+	while (n--)
+		insert_ucs4 (c);
+	IFixMarks(curline, s, curline, curchar);
 }	
 
 /* Tab in to the right place for C mode */
@@ -204,7 +235,7 @@
 		if (strlen (linebuf) == 0)
 		{
 			(void) c_indent();
-			if (curchar == 0)
+			if (bolp())
 				c_tab();
 		}
 		else
@@ -380,7 +411,7 @@
 		if ((curline != line1 || curchar >= char1) &&
 		    (curline != line2 || curchar < char2)) 
 		{
-			if (!linebuf[curchar])
+			if (!cur_char())
 				DelWtSpace();
 			else
 				IndentLine ();
@@ -429,24 +460,33 @@
 		Insert(c);
 }
 
+#define COMPOSE_SEP ':'
+
 char	ComposeSequences[V_STRING_LEN] = 
-"!=|c=#=$=y=|=ss=\" =cr=_a=<=~ =- =rc=__=. =+-=2 =3 =' =,u=pp=..=, =1 =m=>=14=12=34=?=`A='A=^A=~A=\"A=.A=AE=,C=`E='E=^E=\"E=`I='I=^I=\"I=-D=~N=`O='O=^O=~O=\"O=* =/O=`U='U=^U=\"U='Y=TH=SS=`a='a=^a=~a=\"a=.a=ae=,c=`e='e=^e=\"e=`i='i=^i=\"i=-d=~n=`o='o=^o=~o=\"o=/ =/o=`u='u=^u=\"u='y=th=\"y=\377";
+/* Latin 1 Supplement */
+"!:¡|c:¢#:£$:¤y:¥| :¦ss:§\" :¨cr:©_a:ª<<:«~:¬-:­rc:®__:¯"
+". :°+-:±2:²3:³' :´,u:µpp:¶. :·, :¸1:¹m:º>>:»14:¼12:½34:¾?:¿"
+"`A:À'A:Á^A:Â~A:Ã\"A:Ä.A:ÅAE:ÆC,:Ç`E:È'E:É^E:Ê\"E:Ë`I:Ì'I:Í^I:Î\"I:Ï"
+"-D:Ð~N:Ñ`O:Ò'O:Ó^O:Ô~O:Õ\"O:Ö *:×/O:Ø`U:Ù'u:Ú^U:Û\"U:Ü'Y:ÝTH:ÞSS:ß"
+"`a:à'a:á^a:â~a:ã\"a:ä.a:åae:æ,c:ç`e:è'e:é^e:ê\"e:ë`i:ì'i:í^i:î\"i:ï"
+"et:ð~n:ñ`o:ò'o:ó^o:ô~o:õ\"o:ö /:÷/o:ø`u:ù'u:ú^u:û\"u:ü'y:ýth:þ\"y:ÿ"
+/* Currency Symbols */
+"CE:₠/C:₡CR:₢=F:₣=L:₤/m:₥=N:₦PT:₧RS:₨=W:₩NS:₪=d:₫=C:€-K:₭=T:₮DP=₯"
+/* General punctuation */
+"||:‖__:‗` :‘' :’, :‚``:“'':”,,:„+ :†++:‡o :•"
+;
 
 char *
-NextComposeSequence (compose)
-	char *compose;
+NextComposeSequence (char *compose)
 {
+	ucs4	c;
 	if (!compose)
 		return 0;
-	while (*compose && *compose != '=')
-		compose++;
-	if (!*compose)
-		return 0;
-	if (!compose[1])
-		return 0;
-	if (!compose[2])
-		return 0;
-	return compose + 2;
+	while ((c = next_ucs4 (&compose)) && c != ':')
+	    ;
+	if (!c)
+	    return 0;
+	return buf_next (compose);
 }
 
 char *
@@ -466,18 +506,20 @@
     int	    maxlen;
     char    *compose;
     char    *equal;
+    char    *semi;
     int	    nlinespercol;
     int	    nlines;
     int	    col;
     int	    which;
     char    seq[64];
+    char    val[64];
 
     maxlen = 0;
     for (compose = ComposeSequences; 
 	 compose; 
 	 compose = NextComposeSequence (compose))
     {
-	equal = index (compose, '=');
+	equal = index (compose, ':');
 	if (!equal)
 	    break;
 	ncompose++;
@@ -497,18 +539,49 @@
 	    compose = getCompose (which);
 	    if (!compose)
 		break;
-	    equal = index (compose, '=');
+	    equal = index (compose, ':');
 	    if (!equal)
 		break;
+	    semi = buf_next (equal+1);
 	    strncpy (seq, compose, equal - compose);
 	    seq[equal - compose] = '\0';
-	    Typeout ("%c = %-*s", equal[1], maxlen-4, seq);
+	    strncpy (val, equal + 1, semi - (equal + 1));
+	    val[semi - (equal + 1)] = '\0';
+	    Typeout ("%s = %-*s", val, maxlen-4, seq);
 	}
 	Typeout ((char *) 0);
     }
     TOstop ();
 }
 
+#define ishex(c)	(('0' <= (c) && (c) <= '9') || \
+			 ('a' <= (c) && (c) <= 'f') || \
+			 ('A' <= (c) && (c) <= 'F'))
+			 
+HandleUnicode()
+{
+	int	len = 0;
+	ucs4	u = 0, v;
+	int	c, slow;
+	
+	for (;;) {
+		c = waitchar (&slow);
+		if (slow)
+			message (key_strokes);
+		if ('0' <= c && c <= '9')
+			v = c - '0';
+		else if ('a' <= c && c <= 'f')
+			v = c - 'a' + 10;
+		else if ('A' <= c && c <= 'F')
+			v = c - 'A' + 10;
+		else
+			break;
+		u = (u << 4) | v;
+	}
+	if (u)
+		insert_c (u, 1);
+}
+
 HandleCompose()
 {
 	char	sequence[V_STRING_LEN];
@@ -536,9 +609,9 @@
 		}
 		if (!compose)
 			complain("Invalid compose sequence");
-		if (compose[len] == '=')
+		if (compose[len] == ':')
 		{
-			Insert (compose[len+1]);
+			Insert (parse_ucs4(compose+len+1));
 			return;
 		}
 	}
@@ -631,7 +704,7 @@
 {
 #ifdef ABBREV
 	if (MinorMode(Abbrev) && !ismword(LastKeyStruck) &&
-	    !bolp() && ismword(linebuf[curchar - 1]))
+	    !bolp() && ismword(prev_char ()))
 		AbbrevExpand();
 #endif
 #ifdef LISP
@@ -653,7 +726,7 @@
 ins_str(str, ok_nl)
 register char	*str;
 {
-	register char	c;
+	register ucs4	c;
 	Bufpos	save;
 	int	llen;
 
@@ -661,7 +734,8 @@
 		return;		/* ain't nothing to insert! */
 	DOTsave(&save);
 	llen = strlen(linebuf);
-	while (c = *str++) {
+	while (c = parse_ucs4 (str)) {
+		str = buf_next (str);
 		if (c == '\n' || (ok_nl && llen >= LBSIZE - 2)) {
 			IFixMarks(save.p_line, save.p_char, curline, curchar);
 			modify();
@@ -671,7 +745,7 @@
 			llen = strlen(linebuf);
 		}
 		if (c != '\n') {
-			ins_c(c, linebuf, curchar++, 1, LBSIZE);
+			insert_ucs4 (c);
 			llen++;
 		}
 	}
@@ -952,7 +1026,7 @@
 	Bufpos	dot,
 		end;
 
-	if (!isopenp (linebuf[curchar]))
+	if (!isopenp (cur_char ()))
 		complain((char *) 0);
 	DOTsave(&dot);
 	FSexpr();
@@ -1038,7 +1112,7 @@
 
 	SetDot(bp);
 	f_char(1);
-	if (linebuf[curchar] != '(') {
+	if (cur_char () != '(') {
 		register Word	*wp;
 
 		if (specials == NIL)
@@ -1054,10 +1128,10 @@
 			END_TABLE();
 			if (LookingAt("[ \t]*;\\|[ \t]*$", linebuf, curchar))
 				curchar = c_char;
-			else while (linebuf[curchar] == ' ')
-				curchar++;
+			else while (cur_char () == ' ')
+				right_char ();
 		} else
-			curchar++;
+			right_char();
 	}
 	goal = calc_pos(linebuf, curchar);
 	SetDot(&savedot);
@@ -1067,4 +1141,4 @@
 
 	return bp;
 }
-#endif LISP
+#endif /* LISP */

Index: io.c
===================================================================
RCS file: /local/src/CVS/jove/io.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- io.c	11 Jul 2001 06:42:26 -0000	1.3
+++ io.c	15 May 2003 00:01:06 -0000	1.4
@@ -142,7 +142,7 @@
 	strcpy(end, linebuf + curchar);
 	xeof = jove_gets(fp, linebuf + curchar, LBSIZE - curchar);
 	len = strlen (linebuf);
-	if (linebuf[len-1] == '\r') {
+	if (parse_ucs4(buf_prev(linebuf+len, linebuf)) == '\r') {
 		if (!is_insert && AutoCarriageReturn)
 			curbuf->b_minor |= CarriageReturns;
 		if (MinorMode(CarriageReturns))
@@ -471,7 +471,7 @@
 	} while (sp != 0);
 }
 
-#endif CHDIR
+#endif /* CHDIR */
 
 # include	<pwd.h>
 

Index: io.h
===================================================================
RCS file: /local/src/CVS/jove/io.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- io.h	10 Mar 2001 12:23:12 -0000	1.1.1.1
+++ io.h	15 May 2003 00:01:06 -0000	1.2
@@ -15,7 +15,10 @@
 
 extern Terminal	terminal;
 
-#define termoutchar(c)	(--terminal.t_cnt >= 0 ? (*terminal.t_ptr++ = (c)) : termflush((c)))
+#define termoutbyte(c)	(--terminal.t_cnt >= 0 ? (*terminal.t_ptr++ = (c)) : termflush((c)))
+
+void	termoutchar (ucs4 c);
+void	termflush (char c);
 
 #define T_ERR		040
 

Index: iproc.c
===================================================================
RCS file: /local/src/CVS/jove/iproc.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- iproc.c	11 Jul 2001 06:42:26 -0000	1.2
+++ iproc.c	15 May 2003 00:01:06 -0000	1.3
@@ -524,13 +524,11 @@
 proc_kill(p, sig)
 register Process	*p;
 {
-#ifndef LINUX
-	extern char	*sys_errlist[];
-#endif
 	if (isdead(p))
 		return;
 	if (killpg(p->p_pid, sig) == -1)
-		s_mess("Cannot kill %s (%d): %s", p->p_name, p->p_pid, sys_errlist[errno]);
+		s_mess("Cannot kill %s (%d): %s", p->p_name, p->p_pid, 
+		       strerror (errno));
 }
 
 proc_eof (p)
@@ -946,8 +944,8 @@
 {
 	if (!eolp ())
 		complain ("[not at end of line]");
-	while (curchar && !iswhite (linebuf[curchar-1]))
-		--curchar;
+	while (!bolp() && !iswhite (cur_char ()))
+		left_char ();
 	f_complete (c, linebuf + curchar);
 	Eol ();
 }

Index: jove.c
===================================================================
RCS file: /local/src/CVS/jove/jove.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- jove.c	24 Aug 2001 09:02:38 -0000	1.3
+++ jove.c	15 May 2003 00:01:06 -0000	1.4
@@ -35,10 +35,10 @@
 #else
 #ifdef SYSV
 struct Termio	sg1, sg2;
-#else SYSV
+#else /* SYSV */
 struct sgttyb	sg1, sg2;
-#endif SYSV
-#endif BRLUNIX
+#endif /* SYSV */
+#endif /* BRLUNIX */
 
 #ifdef BIFF
 private struct stat	tt_stat;	/* for biff */
@@ -140,7 +140,7 @@
     if (fcntl(fd, F_SETFL, on ? blockf : nonblockf) == -1)
 	finish(SIGHUP);
 }
-#endif SYSV
+#endif /*  SYSV */
 
 Peekc()
 {
@@ -178,7 +178,7 @@
 #else
 		while (nchars < 0 && errno == EINTR);
 		if (nchars <= 0)
-#endif SYSV
+#endif /*  SYSV */
 			finish(SIGHUP);
 		bp = smbuf;
 		InputPending = nchars > 1;
@@ -186,7 +186,7 @@
 	nchars--;
 	return *bp++ & 0377;
 }
-#else PIPEPROCS
+#else /*  PIPEPROCS */
 
 terminchar()
 {
@@ -270,8 +270,8 @@
 	nchars--;
 	return *bp++ & 0377;
 }
-#endif PIPEPROCS
-#else IPROCS
+#endif /*  PIPEPROCS */
+#else /*  IPROCS */
 terminchar()
 {
 	extern int	errno;
@@ -290,7 +290,7 @@
 	nchars--;
 	return *bp++ & 0377;
 }
-#endif IPROCS
+#endif /*  IPROCS */
 
 int	InputPending = 0;
 
@@ -477,7 +477,7 @@
 			*lip = win.ws_row;
 	}
 	}
-#else TIOCGWINSZ
+#else /*  TIOCGWINSZ */
 #ifdef BTL_BLIT
 #include <sys/jioctl.h>
 	{
@@ -490,8 +490,8 @@
 			*lip = jwin.bytesy;
 	}
 	}
-#endif BTL_BLIT
-#endif TIOCGWINSZ
+#endif /*  BTL_BLIT */
+#endif /*  TIOCGWINSZ */
 	/*
 	 * bounds check for absurd values - this will break when terminals get
 	 * more than 1000 characters across or down but I don't think that's
@@ -518,7 +518,7 @@
 		win.ws_row = li;
 		ioctl (0, TIOCSWINSZ, &win);
 	}
-#else TIOCGWINSZ
+#else /*  TIOCGWINSZ */
 #ifdef BTL_BLIT
 #include <sys/jioctl.h>
 	{
@@ -533,8 +533,8 @@
 				*lip = jwin.bytesy;
 		}
 	}
-#endif BTL_BLIT
-#endif TIOCGWINSZ
+#endif /*  BTL_BLIT */
+#endif /*  TIOCGWINSZ */
 }
 
 #ifdef BIFF
@@ -580,7 +580,7 @@
 	(void) ioctl(0, GetAttr, (char *) &sg1);
 #else
 	(void) gtty(0, &sg1);
-#endif SYSV
+#endif /*  SYSV */
 	sg2 = sg1;
 
 #ifdef SYSV
@@ -613,7 +613,7 @@
 	sg2.sg_xflags &= ~((sg2.sg_xflags&DC3DC1 ? 0 : STALL) | PAGE);
 #else
 	sg2.sg_flags &= ~(ECHO | CRMOD);
-#endif BRLUNIX
+#endif /*  BRLUNIX */
 
 #ifdef EUNICE
 	sg2.sg_flags |= RAW;	/* Eunice needs RAW mode last I heard. */
@@ -626,8 +626,8 @@
 #   endif
 #else
 	sg2.sg_flags |= (MetaKey ? RAW : CBREAK);
-#endif PURDUE_EE
-#endif EUNICE
+#endif /*  PURDUE_EE */
+#endif /*  EUNICE */
 #ifdef TIOCSLTC
 	(void) ioctl(0, TIOCGLTC, (struct sgttyb *) &ls1);
 	ls2 = ls1;
@@ -646,8 +646,8 @@
 		tc2.t_stopc = (char) -1;
 		tc2.t_startc = (char) -1;
 	}
-#endif TIOCGETC
-#endif SYSV
+#endif /*  TIOCGETC */
+#endif /*  SYSV */
 }
 
 tty_reset()
@@ -679,16 +679,16 @@
 		perror ("TIOCSETN");
 	}
 	}
-#endif BRLUNIX
-#endif SYSV
+#endif /*  BRLUNIX */
+#endif /*  SYSV */
 
 #ifndef SYSV
 #ifdef TIOCSETC
 	(void) ioctl(0, TIOCSETC, n == 0 ? (struct sgttyb *) &tc1 : (struct sgttyb *) &tc2);
-#endif TIOCSETC
+#endif /*  TIOCSETC */
 #ifdef TIOCSLTC
 	(void) ioctl(0, TIOCSLTC, n == 0 ? (struct sgttyb *) &ls1 : (struct sgttyb *) &ls2);
-#endif TIOCSLTC
+#endif /*  TIOCSLTC */
 #endif
 	done_ttinit = 1;
 #ifdef BIFF
@@ -1471,7 +1471,7 @@
 	sprintf(Mailbox, "/usr/mail/%s", getenv("LOGNAME"));
 #else
 	sprintf(Mailbox, "/usr/spool/mail/%s", getenv("USER"));
-#endif SYSV
+#endif /*  SYSV */
 	(void) joverc(Joverc, 0);
 	if (!scanvec(argv, "-j")) {
 		char	tmpbuf[100];

Index: jove.h
===================================================================
RCS file: /local/src/CVS/jove/jove.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- jove.h	20 Feb 2002 20:34:31 -0000	1.4
+++ jove.h	15 May 2003 00:01:06 -0000	1.5
@@ -134,6 +134,19 @@
 #define CharUpcase(c)	(CaseEquiv[c])
 #define WinText(w)	(((w)->w_flags & W_NUMLINES ? 8 : 0) + ((w)->w_flags & W_HIGHCUR ? 1 : 0))
 
+typedef unsigned int	ucs4;
+
+ucs4 parse_ucs4 (char *buf);
+ucs4 next_ucs4 (char **bufp);
+char *unparse_ucs4 (ucs4 c, char *buf);
+char *buf_next (char *buf);
+char *buf_prev (char *buf, char *first);
+#define char_at(i)	parse_ucs4(linebuf + (i))
+#define cur_char()	char_at(curchar)
+#define prev_char()	parse_ucs4(buf_prev (linebuf + curchar, linebuf))
+#define right_char()	(curchar = buf_next(linebuf+curchar) - linebuf)
+#define left_char()	(curchar = buf_prev(linebuf+curchar,linebuf)-linebuf)
+    
 extern int	OkayAbort,	/* okay to abort redisplay */
 		BufSize;
 
@@ -283,7 +296,7 @@
 # define PROC_IO	0	/* interactive process using pty */
 # define PROC_IN	1	/* non-interactive process using pipe */
 
-#endif IPROCS
+#endif /* IPROCS */
 
 struct window {
 	Window	*w_prev,	/* circular list */
@@ -459,6 +472,7 @@
 extern int
 	OKXonXoff,		/* disable start/stop characters */
 	MetaKey,		/* this terminal has a meta key */
+        Utf8Out,		/* this terminal accepts UTF-8 output */
 	VisBell,		/* use visible bell (if possible) */
 	WrapScan,		/* make searches wrap */
 	phystab,		/* terminal's tabstop settings */ 
@@ -570,15 +584,12 @@
 #define MESG_SIZE SPRINTF_LEN
 extern char	mesgbuf[MESG_SIZE];
 
-#ifdef SEVENBITCHARS
-typedef char screenchar;
-#define INVERSE_BIT 0x80
-#define CHAR_MASK   0x7F
-#else
-typedef short screenchar;
-#define INVERSE_BIT 0x100
-#define CHAR_MASK   0xFF
-#endif
+
+ucs4	next_ucs4(char **bufp);
+    
+typedef ucs4	    screenchar;
+#define INVERSE_BIT 0x80000000
+#define CHAR_MASK   0x7FFFFFFF
 
 struct screenline {
 	screenchar	*s_line,
@@ -685,6 +696,8 @@
 	*mak_buf(),
 	*buf_exists(),
 	*file_exists();
+
+extern void insert_c (ucs4 c, int n);
 
 struct cmd *
 	FindCmd();

Index: keymaps.txt
===================================================================
RCS file: /local/src/CVS/jove/keymaps.txt,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- keymaps.txt	10 Mar 2001 12:23:12 -0000	1.1.1.1
+++ keymaps.txt	15 May 2003 00:01:06 -0000	1.2
@@ -42,7 +42,7 @@
 	"pause-jove",			/* ^Z */
 	"Prefix-1",			/* ^[ */
 	"i-search-forward",		/* ^\ */
-	"unbound",			/* ^] */
+	"handle-unicode",		/* ^] */
 	"quoted-insert",		/* ^^ */
 	"unbound",			/* ^_ */
 	"self-insert",			/*    */

Index: misc.c
===================================================================
RCS file: /local/src/CVS/jove/misc.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- misc.c	11 Jul 2001 06:42:26 -0000	1.2
+++ misc.c	15 May 2003 00:01:06 -0000	1.3
@@ -60,13 +60,13 @@
 
 TransChar()
 {
-	char	before;
+	ucs4	before;
 
-	if (curchar == 0 || (eolp() && curchar == 1))
+	if (bolp() || (eolp() && curchar == 1))
 		complain((char *) 0);	/* BEEP */
 	if (eolp())
 		b_char(1);
-	before = linebuf[curchar - 1];
+	before = prev_char ();
 	del_char(BACKWARD, 1);
 	f_char(1);
 	insert_c(before, 1);
@@ -283,10 +283,10 @@
 
 ToIndent()
 {
-	register char	*cp,
-			c;
+	char	*cp;
+	ucs4	c;
 
-	for (cp = linebuf; c = *cp; cp++)
+	for (cp = linebuf; c = parse_ucs4(cp); cp = buf_next (cp))
 		if (c != ' ' && c != '\t')
 			break;
 	curchar = cp - linebuf;
@@ -294,10 +294,10 @@
 
 AtIndent ()
 {
-	register char	*cp,
-			c;
+	char	*cp;
+	ucs4	c;
 
-	for (cp = linebuf; c = *cp; cp++)
+	for (cp = linebuf; c = parse_ucs4(cp); cp = buf_next (cp))
 		if (c != ' ' && c != '\t')
 			break;
 	return curchar == cp - linebuf;
@@ -405,7 +405,7 @@
 		complain(unsupported);
 	}
 }
-#endif ANSICODES
+#endif /* ANSICODES */
 
 NotModified()
 {

Index: move.c
===================================================================
RCS file: /local/src/CVS/jove/move.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- move.c	10 Mar 2001 12:23:12 -0000	1.1.1.1
+++ move.c	15 May 2003 00:01:06 -0000	1.2
@@ -24,7 +24,7 @@
 				break;
 			SetLine(curline->l_next);
 		} else
-			curchar++;
+			right_char();
 	}
 }
 
@@ -43,7 +43,7 @@
 			SetLine(curline->l_prev);
 			Eol();
 		} else
-			--curchar;
+			left_char ();
 	}
 }
 
@@ -416,9 +416,9 @@
 	} else {
 		extern int	REbom;
 
-		curchar = REbom + 1;	/* Just after the [?.!] */
+		curchar = buf_next (linebuf + REbom) - linebuf;	/* Just after the [?.!] */
 		if (LookingAt("[\")]  *\\|[\")]$", linebuf, curchar))
-			curchar++;
+			right_char ();
 		else if (!eolp() && !LookingAt("  *", linebuf, curchar))
 			to_sent(dir);
 	}
@@ -461,7 +461,7 @@
 f_word(num)
 register int	num;
 {
-	register char	c;
+	ucs4	c;
 
 	if (num < 0) {
 		b_word(-num);
@@ -469,8 +469,8 @@
 	}
 	while (--num >= 0) {
 		to_word(FORWARD);
-		while ((c = linebuf[curchar]) != 0 && isword(c))
-			curchar++;
+		while ((c = cur_char()) != 0 && isword(c))
+			right_char ();
 		if (eobp())
 			break;
 	}
@@ -480,16 +480,14 @@
 b_word(num)
 register int	num;
 {
-	register char	c;
-
 	if (num < 0) {
 		f_word(-num);
 		return;
 	}
 	while (--num >= 0) {
 		to_word(BACKWARD);
-		while (!bolp() && (c = linebuf[curchar - 1], isword(c)))
-			--curchar;
+		while (!bolp() && isword(prev_char ()))
+			left_char ();
 		if (bobp())
 			break;
 	}

Index: paragraph.c
===================================================================
RCS file: /local/src/CVS/jove/paragraph.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- paragraph.c	20 Feb 2002 20:34:31 -0000	1.3
+++ paragraph.c	15 May 2003 00:01:06 -0000	1.4
@@ -387,32 +387,33 @@
 
 do_space()
 {
-	int	c1 = curchar,
-		c2 = c1,
-		diff,
+	int	diff,
 		nspace;
-	char	ch;
+	ucs4	ch;
+	char	*sp = linebuf + curchar, *pp;
+	char	*ep = linebuf + curchar;
 
-	while (c1 > 0 && ((ch = linebuf[c1 - 1]) == ' ' || ch == '\t'))
-		c1--;
-	while ((ch = linebuf[c2]) == ' ' || ch == '\t')
-		c2++;
-	diff = (c2 - c1);
-	curchar = c2;
+	while ((pp = buf_prev (sp, linebuf)) != sp && 
+	       ((ch = parse_ucs4 (pp)) == ' ' || ch == '\t'))
+		sp = pp;
+	while ((ch = parse_ucs4 (ep)) == ' ' || ch == '\t')
+		ep = buf_next (ep);
+	diff = (ep - sp);
+	curchar = ep - linebuf;
 
 	if (diff == 0)
 		return;
-	if (c1 > 0) {
-		int	topunct = c1 - 1;
+	if (sp != linebuf) {
+		pp = buf_prev (sp, linebuf);
 
 		nspace = 1;
 		if (diff >= 2) {
-			while (index("\")]", linebuf[topunct])) {
-				if (topunct == 0)
+			while (index("\")]", parse_ucs4 (pp))) {
+				if (pp == linebuf)
 					break;
-				topunct--;
+				pp = buf_prev (pp, linebuf);
 			}
-			if (index("?!.:", linebuf[topunct]))
+			if (index("?!.:", parse_ucs4 (pp)))
 				nspace = 2;
 		}
 	} else
@@ -454,7 +455,8 @@
 				del_char(FORWARD, 1);	/* Delete line separator. */
 				ins_str("  ", NO);
 			} else {
-				cp = StrIndex(1, linebuf, curchar + 1, ' ');
+				int	n = buf_next (linebuf+curchar)-linebuf;
+				cp = StrIndex(1, linebuf, n, ' ');
 				if (cp == 0)
 					Eol();
 				else

Index: portsrv.c
===================================================================
RCS file: /local/src/CVS/jove/portsrv.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- portsrv.c	10 Mar 2001 12:23:12 -0000	1.1.1.1
+++ portsrv.c	15 May 2003 00:01:06 -0000	1.2
@@ -151,7 +151,7 @@
 	}
 }
 
-#else PIPEPROCS
+#else /* PIPEPROCS */
 main()
 {
 }

Index: proc.c
===================================================================
RCS file: /local/src/CVS/jove/proc.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- proc.c	10 Mar 2001 12:23:12 -0000	1.1.1.1
+++ proc.c	15 May 2003 00:01:06 -0000	1.2
@@ -87,7 +87,7 @@
 		else
 			kill_off(rpid, w);
 	}
-#endif IPROCS
+#endif /* IPROCS */
 }
 
 private int	holdCounts[NSIG];

Index: re1.c
===================================================================
RCS file: /local/src/CVS/jove/re1.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- re1.c	11 Jul 2001 06:42:26 -0000	1.2
+++ re1.c	15 May 2003 00:01:06 -0000	1.3
@@ -51,8 +51,9 @@
 				case BS:
 				case RUBOUT:
 				case 'N':
-					if (linebuf[offset++] == '\0')
+					if (linebuf[offset] == '\0')
 						goto nxtline;
+					offset = buf_next(linebuf+offset)-linebuf;
 					continue;
 
 				case CTL('W'):
@@ -817,12 +818,12 @@
 	char	*tagfname;
 
 	set_max_tag ();
-	if (!ismword(linebuf[curchar]))
+	if (!ismword(cur_char ()))
 		complain("[Not a tag!]");
-	while (c1 > 0 && ismword(linebuf[c1 - 1]))
-		c1--;
-	while (ismword(linebuf[c2]))
-		c2++;
+	while (c1 > 0 && ismword(parse_ucs4 (buf_prev (linebuf + c1, linebuf))))
+		c1 = buf_prev (linebuf+c1, linebuf) - linebuf;
+	while (ismword(parse_ucs4 (linebuf + c2)))
+		c2 = buf_next (linebuf+c2) - linebuf;
 
 	null_ncpy(tagname, linebuf + c1, c2 - c1);
 	find_tag(tagname);
@@ -866,8 +867,8 @@
 		return 0;
 	DOTsave(&buf);
 	if (dir == FORWARD) {
-		if (cmp_char(linebuf[curchar], c)) {
-			buf.p_char = curchar + 1;
+		if (cmp_char(cur_char (), c)) {
+			buf.p_char = buf_next (linebuf+curchar) - linebuf;
 			return &buf;
 		}
 	} else {

Index: recover.c
===================================================================
RCS file: /local/src/CVS/jove/recover.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- recover.c	11 Jul 2001 06:42:26 -0000	1.3
+++ recover.c	15 May 2003 00:01:07 -0000	1.4
@@ -550,7 +550,7 @@
 #ifdef KILL0
 	if (kill(Header.Pid, 0) == 0)
 		return 0;
-#endif KILL0
+#endif /* KILL0 */
 
 	if (Header.Nbuffers == 0) {
 		printf("There are no modified buffers in %s; should I delete the tmp file?", pntrfile);

Index: scandir.c
===================================================================
RCS file: /local/src/CVS/jove/scandir.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- scandir.c	10 Mar 2001 12:23:12 -0000	1.1.1.1
+++ scandir.c	15 May 2003 00:01:07 -0000	1.2
@@ -71,8 +71,8 @@
 	return &dir;
 }
 
-#endif hpux
-#endif BSD4_2
+#endif /* hpux */
+#endif /* BSD4_2 */
 
 /* Scandir returns the number of entries or -1 if the directory cannoot
    be opened or malloc fails. */

Index: screen.c
===================================================================
RCS file: /local/src/CVS/jove/screen.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- screen.c	11 Jul 2001 06:42:26 -0000	1.2
+++ screen.c	15 May 2003 00:01:07 -0000	1.3
@@ -146,8 +146,7 @@
 
 /* Output one character (if necessary) at the current position */
 
-dosputc(c)
-register screenchar	c;
+dosputc(screenchar c)
 {
 	if (*cursor != c) {
 #ifdef ID_CHAR
@@ -193,23 +192,21 @@
    reach the end of the screen.  Aborts if there is a character
    waiting.  */
 
-swrite(line, inversep, abortable)
-register char	*line;
-register int	abortable;
+swrite(char *line, int inversep, int abortable)
 {
-	register int	c;
+	ucs4	c;
 	int	col = i_col,
 		aborted = 0;
-	register int	n = cursend - cursor;
-	int	or_byte = inversep ? INVERSE_BIT : 0,
-		thebyte;
+	int	n = cursend - cursor;
+	ucs4	or_byte = inversep ? INVERSE_BIT : 0;
+	ucs4	thebyte;
 	int	togo = 0;
 
 	if (n <= 0)
 		return 1;
 
 	OkayAbort = 0;
-	while (c = *line++) {
+	while (c = next_ucs4 (&line)) {
 		if (abortable && OkayAbort) {
 			OkayAbort = NO;
 			if (InputPending = charp()) {
@@ -261,7 +258,7 @@
 	register int	n = cursend - cursor,
 			col = 0,
 			c;
-	register char	*bp;
+	char	*bp;
 	int	StartCol = DesiredScreen[linenum].s_offset,
 		visspace = DesiredScreen[linenum].s_window->w_flags & W_VISSPACE,
 		aborted = 0;
@@ -274,7 +271,7 @@
 			break;
 		}
 
-		c = *bp++ & CHAR_MASK;
+		c = next_ucs4 (&bp);
 		if (c == '\t')
 			col += (tabstop - (col % tabstop));
 		else if (isctrl(c))
@@ -284,7 +281,7 @@
 	}
 
 	OkayAbort = 0;
-	while (c = (*bp++ & CHAR_MASK)) {
+	while (c = next_ucs4(&bp)) {
 		if (OkayAbort) {
 			OkayAbort = NO;
 			if (InputPending = charp()) {

Index: temp.h
===================================================================
RCS file: /local/src/CVS/jove/temp.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- temp.h	10 Mar 2001 12:23:12 -0000	1.1.1.1
+++ temp.h	15 May 2003 00:01:07 -0000	1.2
@@ -42,7 +42,7 @@
 #else
 #   define CH_BITS		0
 #   define MAX_BLOCKS		(1 << 20)	/* basically unlimited */
-#endif SMALL
+#endif /* SMALL */
 
 #if LBSIZE == 512
 #    define BNO_SHIFT		(9 - CH_BITS)

Index: term.c
===================================================================
RCS file: /local/src/CVS/jove/term.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- term.c	11 Jul 2001 06:42:26 -0000	1.3
+++ term.c	15 May 2003 00:01:07 -0000	1.4
@@ -78,7 +78,7 @@
 char	PC;
 #else
 extern char	PC;
-#endif SYSV SYSVR2
+#endif /* SYSV SYSVR2 */
 
 static char	tspace[256];
 
@@ -245,7 +245,9 @@
 	/*
 	 * initialize for insert/delete char
 	 */
+#ifdef ID_CHAR
 	disp_opt_init ();
+#endif
 	return 1;
 }
 

Index: tune.h
===================================================================
RCS file: /local/src/CVS/jove/tune.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- tune.h	24 Aug 2001 09:02:38 -0000	1.3
+++ tune.h	15 May 2003 00:01:07 -0000	1.4
@@ -93,7 +93,7 @@
 #   endif
 #
 #   define SUBPROCS	/* only on UNIX systems (NOT INCORPORATED YET) */
-#endif MSDOS
+#endif /* MSDOS */
 
 #ifndef NO_C
 #ifdef SMALL
@@ -112,7 +112,7 @@
 #       define CHDIR		/* cd command and absolute pathnames */
 #	define	KILL0	/* kill(pid, 0) returns 0 if proc exists */
 #       define SPELL		/* spell words and buffer commands */
-#       define ID_CHAR		/* include code to IDchar */
+/* #       define ID_CHAR		/* include code to IDchar */
 #       define WIRED_TERMS	/* include code for wired terminals */
 #       define ANSICODES	/* extra commands that process ANSI codes */
 #	ifdef BSD4_2
@@ -121,7 +121,7 @@
 #   endif
 #   define LISP			/* include the code for Lisp Mode */
 #   define CMT_FMT		/* include the comment formatting routines */
-#endif SMALL
+#endif /* SMALL */
 
 #if !sun
 /* #   define MY_MALLOC	/* use more memory efficient malloc (not on suns) */
@@ -172,4 +172,4 @@
 	TmpFilePath[V_STRING_LEN],/* directory/device to store tmp files */
 	Shell[V_STRING_LEN],	/* shell to use */
 	ShFlags[V_STRING_LEN];
-#endif NOEXTERNS
+#endif /* NOEXTERNS */

Index: util.c
===================================================================
RCS file: /local/src/CVS/jove/util.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- util.c	11 Jul 2001 06:42:26 -0000	1.2
+++ util.c	15 May 2003 00:01:07 -0000	1.3
@@ -328,11 +328,11 @@
 to_word(dir)
 register int	dir;
 {
-	register char	c;
+	ucs4	c;
 
 	if (dir == FORWARD) {
-		while ((c = linebuf[curchar]) != 0 && !isword(c))
-			curchar++;
+		while ((c = cur_char ()) != 0 && !isword(c))
+			right_char ();
 		if (eolp()) {
 			if (curline->l_next == 0)
 				return;
@@ -341,8 +341,8 @@
 			return;
 		}
 	} else {
-		while (!bolp() && (c = linebuf[curchar - 1], !isword(c)))
-			--curchar;
+		while (!bolp() && !isword(prev_char()))
+			left_char ();
 		if (bolp()) {
 			if (curline->l_prev == 0)
 				return;
@@ -754,7 +754,7 @@
 		return 4.0;
 }
 
-# else  LOAD_AV_PROG
+# else /*  LOAD_AV_PROG */
 #  ifdef PROC_FILESYS
 #define LOAD_FILE "/proc/loadavg"
 
@@ -854,10 +854,10 @@
 }
 
 #  endif BSD4_2
-# endif PROC_FILESYS
-# endif LOAD_AV_PROG
-#endif LAVD
-#endif LOAD_AV
+# endif /* PROC_FILESYS */
+# endif /* LOAD_AV_PROG */
+#endif /* LAVD */
+#endif /* LOAD_AV */
 
 /* get the time buf, designated by *timep, from FROM to TO. */
 char *

Index: vars.c
===================================================================
RCS file: /local/src/CVS/jove/vars.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- vars.c	10 Mar 2001 12:23:12 -0000	1.1.1.1
+++ vars.c	15 May 2003 00:01:07 -0000	1.2
@@ -85,6 +85,7 @@
 #ifdef ID_CHAR
 	VARIABLE, "use-i/d-char", &UseIC, V_BOOL,
 #endif
+	VARIABLE, "utf8-output", &Utf8Out, V_BOOL|V_CLRSCREEN,
 	VARIABLE, "visible-bell", &VisBell, V_BOOL,
 	VARIABLE, "wrap-search", &WrapScan, V_BOOL,
 	VARIABLE, "write-files-on-make", &WtOnMk, V_BOOL,