]> git.lizzy.rs Git - plan9front.git/blob - sys/doc/utf.ms
usbehci: use 64-bit base address, remove resetlck, simplify scanpci()
[plan9front.git] / sys / doc / utf.ms
1 .HTML "Hello World or Καλημέρα κόσμε or こんにちは 世界
2 .TL
3 Hello World
4 .br
5 or
6 .br
7 .ft R
8 Καλημέρα κόσμε
9 .ft
10 .br
11 or
12 .br
13 \f(Jpこんにちは 世界\fP
14 .AU
15 Rob Pike
16 Ken Thompson
17 .sp
18 rob,ken@plan9.bell-labs.com
19 .AB
20 .FS
21 Originally appeared, in a slightly different form, in
22 .I
23 Proc. of the Winter 1993 USENIX Conf.,
24 .R
25 pp. 43-50,
26 San Diego
27 .FE
28 Plan 9 from Bell Labs has recently been converted from ASCII
29 to an ASCII-compatible variant of the Unicode Standard, a 16-bit character set.
30 In this paper we explain the reasons for the change,
31 describe the character set and representation we chose,
32 and present the programming models and software changes
33 that support the new text format.
34 Although we stopped short of full internationalization\(emfor
35 example, system error messages are in Unixese, not Japanese\(emwe
36 believe Plan 9 is the first system to treat the representation
37 of all major languages on a uniform, equal footing throughout all its
38 software.
39 .AE
40 .SH
41 Introduction
42 .PP
43 The world is multilingual but most computer systems
44 are based on English and ASCII.
45 The first release of Plan 9 [Pike90], a new distributed operating
46 system from Bell Laboratories, seemed a good occasion
47 to correct this chauvinism.
48 It is easier to make such deep changes when building new systems than
49 by refitting old ones.
50 .PP
51 The ANSI C standard [ANSIC] contains some guidance on the matter of
52 `wide' and `multi-byte' characters but falls far short of
53 solving the myriad associated problems.
54 We could find no literature on how to convert a
55 .I system
56 to larger character sets, although some individual
57 .I programs
58 had been converted.
59 This paper reports what we discovered as we
60 explored the problem of representing multilingual
61 text at all levels of an operating system,
62 from the file system and kernel through
63 the applications and up to the window system
64 and display.
65 .PP
66 Plan 9 has not been `internationalized':
67 its manuals are in English,
68 its error messages are in English,
69 and it can display text that goes from left to right only.
70 But before we can address these other problems,
71 we need to handle, uniformly and comfortably,
72 the textual representation of all the major written languages.
73 That subproblem is richer than we had anticipated.
74 .SH
75 Standards
76 .PP
77 Our first step was to select a standard.
78 At the time (January 1992),
79 there were only two viable options:
80 ISO 10646 [ISO10646] and Unicode [Unicode].
81 The documents describing both proposals were still in the draft stage.
82 .PP
83 The draft of ISO 10646 was not
84 very attractive to us.
85 It defined a sparse set of 32-bit characters,
86 which would be
87 hard to implement
88 and have punitive storage requirements.
89 Also, the draft attempted to
90 mollify national interests by allocating
91 16-bit subspaces to national committees
92 to partition individually.
93 The suggested mode of use was to
94 ``flip'' between separate national
95 standards to implement the international standard.
96 This did not strike us as a sound basis for a character set.
97 As well, transmitting 32-bit values in a byte stream,
98 such as in pipes, would be expensive and hard to implement.
99 Since the standard does not define a byte order for such
100 transmission, the byte stream would also have to carry
101 state to enable the values to be recovered.
102 .PP
103 The Unicode Standard is a proposal by a consortium of mostly American
104 computer companies formed
105 to protest the technical
106 failings of ISO 10646.
107 It defines a uniform 16-bit code based on the
108 principle of unification:
109 two characters are the same if they look the
110 same even though they are from different
111 languages.
112 This principle, called Han unification,
113 allows the large Japanese, Chinese, and Korean
114 character sets to be packed comfortably into a 16-bit representation.
115 .PP
116 We chose the Unicode Standard for its technical merits and because its
117 code space was better defined.
118 Moreover,
119 the Unicode Consortium was derailing the
120 ISO 10646 standard.
121 (Now, in 1995,
122 ISO 10646 is a standard
123 with one 16-bit group defined,
124 which is almost exactly the Unicode Standard.
125 As most people expected, the two standards bodies
126 reached a détente and
127 ISO 10646 and Unicode represent the same character set.)
128 .PP
129 The Unicode Standard defines an adequate character set
130 but an unreasonable representation.
131 It states that all characters
132 are 16 bits wide and are communicated and stored in
133 16-bit units.
134 It also reserves a pair of characters
135 (hexadecimal FFFE and FEFF) to detect byte order
136 in transmitted text, requiring state in the byte stream.
137 (The Unicode Consortium was thinking of files, not pipes.)
138 To adopt this encoding,
139 we would have had to convert all text going
140 into and out of Plan 9 between ASCII and Unicode, which cannot be done.
141 Within a single program, in command of all its input and output,
142 it is possible to define characters as 16-bit quantities;
143 in the context of a networked system with
144 hundreds of applications on diverse machines
145 by different manufacturers,
146 it is impossible.
147 .PP
148 We needed a way to adapt the Unicode Standard to the tools-and-pipes
149 model of text processing embodied by the Unix system.
150 To do that, we
151 needed an ASCII-compatible textual
152 representation of Unicode characters for transmission
153 and storage.
154 In the draft ISO standard there was an informative
155 (non-required)
156 Annex
157 called UTF
158 that provided a byte stream encoding
159 of the 32-bit ISO code.
160 The encoding uses multibyte sequences composed
161 from the 190 printable characters of Latin-1
162 to represent character values larger
163 than 159.
164 .PP
165 The UTF encoding has several good properties.
166 By far the most important is that
167 a byte in the ASCII range 0-127 represents
168 itself in UTF.
169 Thus UTF is backward compatible with ASCII.
170 .PP
171 UTF has other advantages.
172 It is a byte encoding and is
173 therefore byte-order independent.
174 ASCII control characters appear in the byte stream
175 only as themselves, never as an element of a sequence
176 encoding another character,
177 so newline bytes separate lines of UTF text.
178 Finally, ANSI C's
179 .CW strcmp
180 function applied to UTF strings preserves the ordering of Unicode characters.
181 .PP
182 To encode and decode UTF is expensive (involving multiplication,
183 division, and modulo operations) but workable.
184 UTF's major disadvantage is that the encoding
185 is not self-synchronizing.
186 It is in general impossible to find the character
187 boundaries in a UTF string without reading from
188 the beginning of the string, although in practice
189 control characters such as newlines,
190 tabs, and blanks provide synchronization points.
191 .PP
192 In August 1992,
193 X-Open circulated a proposal for another UTF-like
194 byte encoding of Unicode characters.
195 Their major concern was that an embedded character
196 in a file name
197 (in particular a slash)
198 could be part of an escape sequence in UTF and
199 therefore confuse a traditional file system.
200 Their proposal would allow all 7-bit ASCII characters
201 to represent themselves
202 .I "and only themselves"
203 in text.
204 Multibyte sequences would contain only characters
205 with the high bit set.
206 We proposed a modification to the new UTF that
207 would address our synchronization problem.
208 Our proposal, which was  originally known informally as UTF-2 and FSS-UTF,
209 is now referred to as UTF-8 and has been approved by ISO to become
210 Annex P to ISO 10646.
211 .PP
212 The model for text in Plan 9 is chosen from these
213 three standards*:
214 .FS
215 * ``That's the nice thing about standards\(emthere's so many to choose from.'' \- Andy Tannenbaum (no, the other one)
216 .FE
217 the Unicode character set encoded as a byte stream by
218 UTF-8, from
219 (soon to be) Annex P of ISO 10646.
220 Although this mixture may seem like a precarious position for us to adopt,
221 it is not as bad as it sounds.
222 ISO 10646 and the Unicode Standard have converged,
223 other systems such as Linux have adopted the same character set and encoding,
224 and the general feeling seems to be that Unicode and UTF-8 will be accepted as the way
225 to exchange text between systems.
226 The prognosis for wide acceptance is good.
227 .PP
228 There are a couple of aspects of the Unicode Standard we have not faced.
229 One is the issue of right-to-left text such as Hebrew or Arabic.
230 Since that is an issue of display, not representation, we believe
231 we can defer that problem for the moment without affecting our
232 ability to solve it later.
233 Another issue is diacriticals and `combining characters',
234 which cause overstriking of multiple Unicode characters.
235 Although necessary for some scripts, such as Thai, Arabic, and Hebrew,
236 such characters confuse the issues for Latin languages because they
237 generate multiple representations for accented characters.
238 ISO 10646 describes three levels of implementation;
239 in Plan 9 we decided not to address the issue.
240 Again, this can be labeled as a display issue and its finer points are still being debated,
241 so we felt comfortable deferring.  Mañana.
242 .PP
243 Although we converted Plan 9 in the altruistic interests of
244 serving foreign languages, we have found the large character
245 set attractive for other reasons.  The Unicode Standard includes many
246 characters\(emmathematical symbols, scientific notation,
247 more general punctuation, and more\(emthat we now use
248 daily in our work.  We no longer test our imaginations
249 to find ways to include non-ASCII symbols in our text;
250 why type
251 .CW :-)
252 when you can use the character ☺?
253 Most compelling is the ability to absorb documents
254 and data that contain non-ASCII characters; our browser for the
255 Oxford English Dictionary
256 lets us see the dictionary as it really is, with pronunciation
257 in the IPA font, foreign phrases properly rendered, and so on,
258 .I "in plain text.
259 .PP
260 In the rest of this paper, except when
261 stated otherwise, the term `UTF' refers to the UTF-8 encoding
262 of Unicode characters as adopted by Plan 9.
263 .SH
264 C Compiler
265 .PP
266 The first program to be converted to UTF
267 was the C Compiler.
268 There are two levels of conversion.
269 On the syntactic level,
270 input to the C compiler
271 is UTF; on the semantic level,
272 the C language needs to define
273 how compiled programs manipulate
274 the UTF set.
275 .PP
276 The syntactic part is simple.
277 The ANSI C language standard defines the
278 source character set to be ASCII.
279 Since UTF is backward compatible with ASCII,
280 the compiler needs little change.
281 The only places where a larger character set
282 is allowed are in character constants, strings, and comments.
283 Since 7-bit ASCII characters can represent only
284 themselves in UTF,
285 the compiler does not have to be careful while looking
286 for the termination of a string or comment.
287 .PP
288 The Plan 9 compiler extends ANSI C to treat any Unicode
289 character with a value outside of the ASCII range as
290 an alphabetic.
291 To a Greek programmer or an English mathematician,
292 α is a sensible and now valid variable name.
293 .PP
294 On the semantic level, ANSI C allows,
295 but does not tie down,
296 the notion of a
297 .I "wide character
298 and admits string and character constants
299 of this type.
300 We chose the wide character type to be
301 .CW unsigned
302 .CW short .
303 In the libraries, the word
304 .CW Rune
305 is defined by a
306 .CW typedef
307 to be equivalent to
308 .CW unsigned
309 .CW short
310 and is
311 used to signify a Unicode character.
312 .PP
313 There are surprises; for example:
314 .P1
315 L'x'    \f1is 120\fP
316 \&'x'   \f1is 120\fP
317 L'ÿ'   \f1is 255\fP
318 \&'ÿ'  \f1is -1, stdio \fPEOF\f1 (if \fPchar\f1 is signed)\fP
319 L'\f1α\fP'     \f1is 945\fP
320 \&'\f1α\fP'    \f1is illegal\fP
321 .P2
322 In the string constants,
323 .P1
324 "\f(Jpこんにちは 世界\fP"
325 L"\f(Jpこんにちは 世界\fP",
326 .P2
327 the former is an array of
328 .CW chars
329 with 22 elements
330 and a null byte,
331 while the latter is an array of
332 .CW unsigned
333 .CW shorts
334 .CW Runes ) (
335 with 8 elements and a null
336 .CW Rune .
337 .PP
338 The Plan 9 library provides an output conversion function,
339 .CW print
340 (analogous to
341 .CW printf ),
342 with formats
343 .CW %c ,
344 .CW %C ,
345 .CW %s ,
346 and
347 .CW %S .
348 Since
349 .CW print
350 produces text, its output is always UTF.
351 The character conversion
352 .CW %c
353 (lower case) masks its argument
354 to 8 bits before converting to UTF.
355 Thus
356 .CW L'ÿ'
357 and
358 .CW 'ÿ'
359 printed under
360 .CW %c
361 will be identical,
362 but
363 .CW L'\f1α\fP'
364 will print as the Unicode
365 character with decimal value 177.
366 The character conversion
367 .CW %C
368 (upper case) masks its argument
369 to 16 bits before converting to UTF.
370 Thus
371 .CW L'ÿ'
372 and
373 .CW L'\f1α\fP'
374 will print correctly under
375 .CW %C ,
376 but
377 .CW 'ÿ'
378 will not.
379 The conversion
380 .CW %s
381 (lower case)
382 expects a pointer to
383 .CW char
384 and copies UTF sequences up to a null byte.
385 The conversion
386 .CW %S
387 (upper case) expects a pointer to
388 .CW Rune
389 and
390 performs sequential
391 .CW %C
392 conversions until a null
393 .CW Rune
394 is encountered.
395 .PP
396 Another problem in format conversion
397 is the definition of
398 .CW %10s :
399 does the number refer to bytes or characters?
400 We decided that such formats were most
401 often used to align output columns and
402 so made the number count characters.
403 Some programs, however, use the count
404 to place blank-padded strings
405 in fixed-sized arrays.
406 These programs must be found and corrected.
407 .PP
408 Here is a complete example:
409 .P1
410 #include <u.h>
411
412 char c[] = "\f(Jpこんにちは 世界\fP";
413 Rune s[] = L"\f(Jpこんにちは 世界\fP";
414
415 main(void)
416 {
417         print("%d, %d\en", sizeof(c), sizeof(s));
418         print("%s\en", c);
419         print("%S\en", s);
420 }
421 .P2
422 .PP
423 This program prints
424 .CW 23,
425 .CW 18
426 and then two identical lines of
427 UTF text.
428 In practice,
429 .CW %S
430 and
431 .CW L"..."
432 are rare in programs; one reason is
433 that most formatted I/O is done in unconverted UTF.
434 .SH
435 Ramifications
436 .PP
437 All programs in Plan 9 now read and write text as UTF, not ASCII.
438 This change breaks two deep-rooted symmetries implicit in most C programs:
439 .IP 1.
440 A character is no longer a
441 .CW char .
442 .IP 2.
443 The internal representation (Rune) of a character now differs from its
444 external representation (UTF).
445 .PP
446 In the sections that follow,
447 we show how these issues were faced in the layers of
448 system software from the operating system up to the applications.
449 The effects are wide-reaching and often surprising.
450 .SH
451 Operating system
452 .PP
453 Since UTF is the only format for text in Plan 9,
454 the interface to the operating system had to be converted to UTF.
455 Text strings cross the interface in several places:
456 command arguments,
457 file names,
458 user names (people can log in using their native name),
459 error messages,
460 and miscellaneous minor places such as commands to the I/O system.
461 Little change was required: null-terminated UTF strings
462 are equivalent to null-terminated ASCII strings for most purposes
463 of the operating system.
464 The library routines described in the next section made that
465 change straightforward.
466 .PP
467 The window system, once called
468 .CW 8.5 ,
469 is now rightfully called
470 .CW 8½ .
471 .SH
472 Libraries
473 .PP
474 A header file included by all programs (see [Pike92]) declares
475 the
476 .CW Rune
477 type to hold 16-bit character values:
478 .P1
479 typedef unsigned short Rune;
480 .P2
481 Also defined are several constants relevant to UTF:
482 .P1
483 enum
484 {
485     UTFmax    = 3,    /* maximum bytes per rune */
486     Runesync  = 0x80, /* can't appear in UTF sequence (<) */
487     Runeself  = 0x80, /* rune==UTF sequence (<) */
488     Runeerror = 0x80, /* decoding error in UTF */
489 };
490 .P2
491 (With the original UTF,
492 .CW Runesync
493 was hexadecimal 21 and
494 .CW Runeself
495 was A0.)
496 .CW UTFmax
497 bytes are sufficient
498 to hold the UTF encoding of any Unicode character.
499 Characters of value less than
500 .CW Runesync
501 only appear in a UTF string as
502 themselves, never as part of a sequence encoding another character.
503 Characters of value less than
504 .CW Runeself
505 encode into single bytes
506 of the same value.
507 Finally, when the library detects errors in UTF input\(embyte sequences
508 that are not valid UTF sequences\(emit converts the first byte of the
509 error sequence to the character
510 .CW Runeerror .
511 There is little a rune-oriented program can do when given bad data
512 except exit, which is unreasonable, or carry on.
513 Originally the conversion routines, described below,
514 returned errors when given invalid UTF,
515 but we found ourselves repeatedly checking for errors and ignoring them.
516 We therefore decided to convert a bad sequence to a valid rune
517 and continue processing.
518 (The ANSI C routines, on the other hand, return errors.)
519 .PP
520 This technique does have the unfortunate property that converting
521 invalid UTF byte strings in and out of runes does not preserve the input,
522 but this circumstance only occurs when non-textual input is
523 given to a textual program.
524 The Unicode Standard defines an error character, value FFFD, to stand for
525 characters from other sets that it does not represent.
526 The
527 .CW Runeerror
528 character is a different concept, related to the encoding rather than the character set, so we
529 chose a different character for it.
530 .PP
531 The Plan 9 C library contains a number of routines for
532 manipulating runes.
533 The first set converts between runes and UTF strings:
534 .P1
535 extern  int     runetochar(char*, Rune*);
536 extern  int     chartorune(Rune*, char*);
537 extern  int     runelen(long);
538 extern  int     fullrune(char*, int);
539 .P2
540 .CW Runetochar
541 translates a single
542 .CW Rune
543 to a UTF sequence and returns the number of bytes produced.
544 .CW Chartorune
545 goes the other way, reporting how many bytes were consumed.
546 .CW Runelen
547 returns the number of bytes in the UTF encoding of a rune.
548 .CW Fullrune
549 examines a UTF string up to a specified number of bytes
550 and reports whether the string begins with a complete UTF encoding.
551 All these routines use the
552 .CW Runeerror
553 character to work around encoding problems.
554 .PP
555 There is also a set of routines for examining null-terminated UTF strings,
556 based on the model of the ANSI standard
557 .CW str
558 routines, but with
559 .CW utf
560 substituted for
561 .CW str
562 and
563 .CW rune
564 for
565 .CW chr :
566 .P1
567 extern  int     utflen(char*);
568 extern  char*   utfrune(char*, long);
569 extern  char*   utfrrune(char*, long);
570 extern  char*   utfutf(char*, char*);
571 .P2
572 .CW Utflen
573 returns the number of runes in a UTF string;
574 .CW utfrune
575 returns a pointer to the first occurrence of a rune in a UTF string;
576 and
577 .CW utfrrune
578 a pointer to the last.
579 .CW Utfutf
580 searches for the first occurrence of a UTF string in another UTF string.
581 Given the synchronizing property of UTF-8,
582 .CW utfutf
583 is the same as
584 .CW strstr
585 if the arguments point to valid UTF strings.
586 .PP
587 It is a mistake to use
588 .CW strchr
589 or
590 .CW strrchr
591 unless searching for a 7-bit ASCII character, that is, a character
592 less than
593 .CW Runeself .
594 .PP
595 We have no routines for manipulating null-terminated arrays of
596 .CW Runes .
597 Although they should probably exist for completeness, we have
598 found no need for them, for the same reason that
599 .CW %S
600 and
601 .CW L"..."
602 are rarely used.
603 .PP
604 Most Plan 9 programs use a new buffered I/O library, BIO, in place of
605 Standard I/O.
606 BIO contains routines to read and write UTF streams, converting to and from
607 runes.
608 .CW Bgetrune
609 returns, as a
610 .CW Rune
611 within a
612 .CW long ,
613 the next character in the UTF input stream;
614 .CW Bputrune
615 takes a rune and writes its UTF representation.
616 .CW Bungetrune
617 puts a rune back into the input stream for rereading.
618 .PP
619 Plan 9 programs use a simple set of macros to process command line arguments.
620 Converting these macros to UTF automatically updated the
621 argument processing of most programs.
622 In general,
623 argument flag names can no longer be held in bytes and
624 arrays of 256 bytes cannot be used to hold a set of flags.
625 .PP
626 We have done nothing analogous to ANSI C's locales, partly because
627 we do not feel qualified to define locales and partly because we remain
628 unconvinced of that model for dealing with the problems.
629 That is really more an issue of internationalization than conversion
630 to a larger character set; on the other hand,
631 because we have chosen a single character set that encompasses
632 most languages, some of the need for
633 locales is eliminated.
634 (We have a utility,
635 .CW tcs ,
636 that translates between UTF and other character sets.)
637 .PP
638 There are several reasons why our library does not follow the ANSI design
639 for wide and multi-byte characters.
640 The ANSI model was designed by a committee, untried, almost
641 as an afterthought, whereas
642 we wanted to design as we built.
643 (We made several major changes to the interface
644 as we became familiar with the problems involved.)
645 We disagree with ANSI C's handling of invalid multi-byte sequences.
646 Also, the ANSI C library is incomplete:
647 although it contains some crucial routines for handling
648 wide and multi-byte characters, there are some serious omissions.
649 For example, our software can exploit
650 the fact that UTF preserves ASCII characters in the byte stream.
651 We could remove that assumption by replacing all
652 calls to
653 .CW strchr
654 with
655 .CW utfrune
656 and so on.
657 (Because of the weaker properties of the original UTF,
658 we have actually done so.)
659 ANSI C cannot:
660 the standard says nothing about the representation, so portable code should
661 .I never
662 call
663 .CW strchr ,
664 yet there is no ANSI equivalent to
665 .CW utfrune .
666 ANSI C simultaneously invalidates
667 .CW strchr
668 and offers no replacement.
669 .PP
670 Finally, ANSI did nothing to integrate wide characters
671 into the I/O system: it gives no method for printing
672 wide characters.
673 We therefore needed to invent some things and decided to invent
674 everything.
675 In the end, some of our entry points do correspond closely to
676 ANSI routines\(emfor example
677 .CW chartorune
678 and
679 .CW runetochar
680 are similar to
681 .CW mbtowc
682 and
683 .CW wctomb \(embut
684 Plan 9's library defines more functionality, enough
685 to write real applications comfortably.
686 .SH
687 Converting the tools
688 .PP
689 The source for our tools and applications had already been converted to
690 work with Latin-1, so it was `8-bit safe', but the conversion to the Unicode
691 Standard and UTF is more involved.
692 Some programs needed no change at all:
693 .CW cat ,
694 for instance,
695 interprets its argument strings, delivered in UTF,
696 as file names that it passes uninterpreted to the
697 .CW open
698 system call,
699 and then just copies bytes from its input to its output;
700 it never makes decisions based on the values of the bytes.
701 (Plan 9
702 .CW cat
703 has no options such as
704 .CW -v
705 to complicate matters.)
706 Most programs, however, needed modest change.
707 .PP
708 It is difficult to
709 find automatically the places that need attention,
710 but
711 .CW grep
712 helps.
713 Software that uses the libraries conscientiously can be searched
714 for calls to library routines that examine bytes as characters:
715 .CW strchr ,
716 .CW strrchr ,
717 .CW strstr ,
718 etc.
719 Replacing these by calls to
720 .CW utfrune ,
721 .CW utfrrune ,
722 and
723 .CW utfutf
724 is enough to fix many programs.
725 Few tools actually need to operate on runes internally;
726 more typically they need only to look for the final slash in a file
727 name and similar trivial tasks.
728 Of the 170 C source programs in the top levels of
729 .CW /sys/src/cmd ,
730 only 23 now contain the word
731 .CW Rune .
732 .PP
733 The programs that
734 .I do
735 store runes internally
736 are mostly those whose
737 .I raison
738 .I d'être
739 is character manipulation:
740 .CW sam
741 (the text editor),
742 .CW sed ,
743 .CW sort ,
744 .CW tr ,
745 .CW troff ,
746 .CW 8½
747 (the window system and terminal emulator),
748 and so on.
749 To decide whether to compute using runes
750 or UTF-encoded byte strings requires balancing the cost of converting
751 the data when read and written
752 against the cost of converting relevant text on demand.
753 For programs such as editors that run a long time with a relatively
754 constant dataset, runes are the better choice.
755 There are space considerations too, but they are more complicated:
756 plain ASCII text grows when converted to runes; UTF-encoded Japanese
757 shrinks.
758 .PP
759 Again, it is hard to automate the conversion of a program from
760 .CW chars
761 to
762 .CW Runes .
763 It is not enough just to change the type of variables; the assumption
764 that bytes and characters are equivalent can be insidious.
765 For instance, to clear a character array by
766 .P1
767 memset(buf, 0, BUFSIZE)
768 .P2
769 becomes wrong if
770 .CW buf
771 is changed from an array of
772 .CW chars
773 to an array of
774 .CW Runes .
775 Any program that indexes tables based on character values needs
776 rethinking.
777 Consider
778 .CW tr ,
779 which originally used multiple 256-byte arrays for the mapping.
780 The naïve conversion would yield multiple 65536-rune arrays.
781 Instead Plan 9
782 .CW tr
783 saves space by building in effect
784 a run-encoded version of the map.
785 .PP
786 .CW Sort
787 has related problems.
788 The cooperation of UTF and
789 .CW strcmp
790 means that a simple sort\(emone with no options\(emcan be done
791 on the original UTF strings using
792 .CW strcmp .
793 With sorting options enabled, however,
794 .CW sort
795 may need to convert its input to runes: for example,
796 option
797 .CW -t\f1α\fP
798 requires searching for alphas in the input text to
799 crack the input into fields.
800 The field specifier
801 .CW +3.2
802 refers to 2 runes beyond the third field.
803 Some of the other options are hopelessly provincial:
804 consider the case-folding and dictionary order options
805 (Japanese doesn't even have an official dictionary order) or
806 .CW -M
807 which compares by case-insensitive English month name.
808 Handling these options involves the
809 larger issues of internationalization and is beyond the scope
810 of this paper and our expertise.
811 Plan 9
812 .CW sort
813 works sensibly with options that make sense relative to the input.
814 The simple and most important options are, however, usually meaningful.
815 In particular,
816 .CW sort
817 sorts UTF into the same order that
818 .CW look
819 expects.
820 .PP
821 Regular expression-matching algorithms need rethinking to
822 be applied to UTF text.
823 Deterministic automata are usually applied to bytes;
824 converting them to operate on variable-sized byte sequences is awkward.
825 On the other hand, converting the input stream to runes adds measurable
826 expense
827 and the state tables expand
828 from size 256 to 65536; it can be expensive just to generate them.
829 For simple string searching,
830 the Boyer-Moore algorithm works with UTF provided the input is
831 guaranteed to be only valid UTF strings; however, it does not work
832 with the old UTF encoding.
833 At a more mundane level, even character classes are harder:
834 the usual bit-vector representation within a non-deterministic automaton
835 is unwieldy with 65536 characters in the alphabet.
836 .PP
837 We compromised.
838 An existing library for compiling and executing regular expressions
839 was adapted to work on runes, with two entry points for searching
840 in arrays of runes and arrays of chars (the pattern is always UTF text).
841 Character classes are represented internally as runs of runes;
842 the reserved value
843 .CW FFFF
844 marks the end of the class.
845 Then
846 .I all
847 utilities that use regular expressions\(emeditors,
848 .CW grep ,
849 .CW awk ,
850 etc.\(emexcept the shell, whose notation
851 was grandfathered, were converted to use the library.
852 For some programs, there was a concomitant loss of performance,
853 but there was also a strong advantage.
854 To our knowledge, Plan 9 is the only Unix-like system
855 that has a single definition and implementation of
856 regular expressions; patterns are written and interpreted
857 identically by all the programs in the system.
858 .PP
859 A handful of programs have the notion of character built into them
860 so strongly as to confuse the issue of what they should do with UTF input.
861 Such programs were treated as individual special cases.
862 For example,
863 .CW wc
864 is, by default, unchanged in behavior and output; a new option,
865 .CW -r ,
866 counts the number of correctly encoded runes\(emvalid UTF sequences\(emin
867 its input;
868 .CW -b
869 the number of invalid sequences.
870 .PP
871 It took us several months to convert all the software in the system
872 to the Unicode Standard and the old UTF.
873 When we decided to convert from that to the new UTF,
874 only three things needed to be done.
875 First, we rewrote the library routines to encode and decode the
876 new UTF.  This took an evening.
877 Next, we converted all the files containing UTF
878 to the new encoding.
879 We wrote a trivial program to look for non-ASCII bytes in
880 text files and used a Plan 9 program called
881 .CW tcs
882 (translate character set) to change encodings.
883 Finally, we recompiled all the system software;
884 the library interface was unchanged, so recompilation was sufficient
885 to effect the transformation.
886 The second two steps were done concurrently and took an afternoon.
887 We concluded that the actual encoding is relatively unimportant to the
888 software; the adoption of large characters and a byte-stream encoding
889 .I per
890 .I se
891 are much deeper issues.
892 .SH
893 Graphics and fonts
894 .PP
895 Plan 9 provides only minimal support for plain text terminals.
896 It is instead designed to be used with all character input and
897 output mediated by a window system such as
898 .CW 8½ .
899 The window system and related software are responsible for the
900 display of UTF text as Unicode character images.
901 For plain text, the window system must provide a user-settable
902 .I font
903 that provides a (possibly empty) picture for each Unicode character.
904 Fancier applications that use bold and Italic characters
905 need multiple fonts storing multiple pictures for each
906 Unicode value.
907 All the issues are apparent, though,
908 in just the problem of
909 displaying a single image for each character, that is, the
910 Unicode equivalent of a plain text terminal.
911 With 128 or even 256 characters, a font can be just
912 an array of bitmaps.  With 65536 characters,
913 a more sophisticated design is necessary.  To store the ideographs
914 for just Japanese as 16×16×1 bit images,
915 the smallest they can reasonably be, takes over a quarter of a
916 megabyte.  Make the images a little larger, store more bits per
917 pixel, and hold a copy in every running application, and the
918 memory cost becomes unreasonable.
919 .PP
920 The structure of the bitmap graphics services is described at length elsewhere
921 [Pike91].
922 In summary, the memory holding the bitmaps is stored in the same machine that has
923 the display, mouse, and keyboard: the terminal in Plan 9 terminology,
924 the workstation in others'.
925 Access to that memory and associated services is provided
926 by device files served by system
927 software on the terminal.  One of those files,
928 .CW /dev/bitblt ,
929 interprets messages written upon it as requests for actions
930 corresponding to entry points in the graphics library:
931 allocate a bitmap, execute a raster operation, draw a text string, etc.
932 The window system
933 acts as a multiplexer that mediates access to the services
934 and resources of the terminal by simulating in each client window
935 a set of files mirroring those provided by the system.
936 That is, each window has a distinct
937 .CW /dev/mouse ,
938 .CW /dev/bitblt ,
939 and so on through which applications drive graphical
940 input and output.
941 .PP
942 One of the resources managed by
943 .CW 8½
944 and the terminal is the set of active
945 .I subfonts.
946 Each subfont holds the
947 bitmaps and associated data structures for a sequential set of Unicode
948 characters.
949 Subfonts are stored in files and loaded into the terminal by
950 .CW 8½
951 or an application.
952 For example, one subfont
953 might hold the images of the first 256 characters of the Unicode space,
954 corresponding to the Latin-1 character set;
955 another might hold the standard phonetic character set, Unicode characters
956 with value 0250 to 02E9.
957 These files are collected in directories corresponding to typefaces:
958 .CW /lib/font/bit/pelm
959 contains the Pellucida Monospace character set, with subfonts holding
960 the Latin-1, Greek, Cyrillic and other components of the typeface.
961 A suffix on subfont files encodes (in a subfont-specific
962 way) the size of the images:
963 .CW /lib/font/bit/pelm/latin1.9
964 contains the Latin-1 Pellucida Monospace characters with lower
965 case letters 9 pixels high;
966 .CW /lib/font/bit/jis/jis5400.16
967 contains 16-pixel high
968 ideographs starting at Unicode value 5400.
969 .PP
970 The subfonts do not identify which portion of the Unicode space
971 they cover.  Instead, a
972 font file, in plain text,
973 describes how to assemble subfonts into a complete
974 character set.
975 The font file is presented as an argument to the window system
976 to determine how plain text is displayed in text windows and
977 applications.
978 Here is the beginning of the font file
979 .CW /lib/font/bit/pelm/jis.9.font ,
980 which describes the layout of a font covering that portion of
981 the Unicode Standard for which we have characters of typical
982 display size, using Japanese characters
983 to cover the Han space:
984 .P1
985 18      14
986 0x0000  0x00FF  latin1.9
987 0x0100  0x017E  latineur.9
988 0x0250  0x02E9  ipa.9
989 0x0386  0x03F5  greek.9
990 0x0400  0x0475  cyrillic.9
991 0x2000  0x2044  ../misc/genpunc.9
992 0x2070  0x208E  supsub.9
993 0x20A0  0x20AA  currency.9
994 0x2100  0x2138  ../misc/letterlike.9
995 0x2190  0x21EA  ../misc/arrows
996 0x2200  0x227F  ../misc/math1
997 0x2280  0x22F1  ../misc/math2
998 0x2300  0x232C  ../misc/tech
999 0x2500  0x257F  ../misc/chart
1000 0x2600  0x266F  ../misc/ding
1001 .P2
1002 .P1
1003 0x3000  0x303f  ../jis/jis3000.16
1004 0x30a1  0x30fe  ../jis/katakana.16
1005 0x3041  0x309e  ../jis/hiragana.16
1006 0x4e00  0x4fff  ../jis/jis4e00.16
1007 0x5000  0x51ff  ../jis/jis5000.16
1008 \&...
1009 .P2
1010 The first two numbers set the interline spacing of the font (18
1011 pixels) and the distance from the baseline to the top of the
1012 line (14 pixels).
1013 When characters are displayed, they are placed so as best
1014 to fit within those constraints; characters
1015 too large to fit will be truncated.
1016 The rest of the file associates subfont files
1017 with portions of Unicode space.
1018 The first four such files are in the Pellucida Monospace typeface
1019 and directory; others reside in other directories.  The file names
1020 are relative to the font file's own location.
1021 .PP
1022 There are several advantages to this two-level structure.
1023 First, it simultaneously breaks the huge Unicode space into manageable
1024 components and provides a unifying architecture for
1025 assembling fonts from disjoint pieces.
1026 Second, the structure promotes sharing.
1027 For example, we have only one set of Japanese
1028 characters but dozens of typefaces for the Latin-1 characters,
1029 and this structure permits us to store only one copy of the
1030 Japanese set but use it with any Roman typeface.
1031 Also, customization is easy.
1032 English-speaking users who don't need Japanese characters
1033 but may want to read an on-line Oxford English Dictionary can
1034 assemble a custom font with the
1035 Latin-1 (or even just ASCII) characters and the International
1036 Phonetic Alphabet (IPA).
1037 Moreover, to do so requires just editing a plain text file,
1038 not using a special font editing tool.
1039 Finally, the structure guides the design of
1040 caching protocols to improve performance and memory usage.
1041 .PP
1042 To load a complete Unicode character set into each application
1043 would consume too
1044 much memory and, particularly on slow terminal lines, would take
1045 unreasonably long.
1046 Instead, Plan 9 assembles a multi-level cache structure for
1047 each font.
1048 An application opens a font file, reads and parses it,
1049 and allocates a data structure.
1050 A message written to
1051 .CW /dev/bitblt
1052 allocates an associated structure held in the terminal, in particular,
1053 a bitmap to act as a cache
1054 for recently used character images.
1055 Other messages copy these images to bitmaps such as the screen
1056 by loading characters from subfonts into the cache on demand and
1057 from there to the destination bitmap.
1058 The protocol to draw characters is in terms of cache indices,
1059 not Unicode character number or UTF sequences.
1060 These details are hidden from the application, which instead
1061 sees only a subroutine to draw a string in a bitmap from a
1062 given font, functions to discover character size information,
1063 and routines to allocate and to free fonts.
1064 .PP
1065 As needed, whole
1066 subfonts are opened by the graphics library, read, and then downloaded
1067 to the terminal.
1068 They are held open by the library in an LRU-replacement list.
1069 Even when the program closes a subfont, it is retained
1070 in the terminal for later use.
1071 When the application opens the subfont, it asks the terminal
1072 if it already has a copy to avoid reading it from the file
1073 server if possible.
1074 This level of cache has the property that the bitmaps for, say,
1075 all the Japanese characters are stored only once, in the terminal;
1076 the applications read only size and width information from the terminal
1077 and share the images.
1078 .PP
1079 The sizes of the character and subfont caches held by the
1080 application are adaptive.
1081 A simple algorithm monitors the cache miss rate to enlarge and
1082 shrink the caches as required.
1083 The size of the character cache is limited to 2048 images maximum,
1084 which in practice seems enough even for Japanese text.
1085 For plain ASCII-like text it naturally stays around 128 images.
1086 .PP
1087 This mechanism sounds complicated but is implemented by only about
1088 500 lines in the library and considerably less in each of the
1089 terminal's graphics driver and
1090 .CW 8½ .
1091 It has the advantage that only characters that are
1092 being used are loaded into memory.
1093 It is also efficient: if the characters being drawn
1094 are in the cache the extra overhead is negligible.
1095 It works particularly well for alphabetic character sets,
1096 but also adapts on demand for ideographic sets.
1097 When a user first looks at Japanese text, it takes a few
1098 seconds to read all the font data, but thereafter the
1099 text is drawn almost as fast as regular text (the images
1100 are larger, so draw a little slower).
1101 Also, because the bitmaps are remembered by the terminal,
1102 if a second application then looks at Japanese text
1103 it starts faster than the first.
1104 .PP
1105 We considered
1106 building a `font server'
1107 to cache character images and associated data
1108 for the applications, the window system, and the terminal.
1109 We rejected this design because, although isolating
1110 many of the problems of font management into a separate program,
1111 it didn't simplify the applications.
1112 Moreover, in a distributed system such as Plan 9 it is easy
1113 to have too many special purpose servers.
1114 Making the management of the fonts the concern of only
1115 the essential components simplifies the system and makes
1116 bootstrapping less intricate.
1117 .SH
1118 Input
1119 .PP
1120 A completely different problem is how to type Unicode characters
1121 as input to the system.
1122 We selected an unused key on our ASCII keyboards
1123 to serve as a prefix for multi-keystroke
1124 sequences that generate Unicode characters.
1125 For example, the character
1126 .CW ü
1127 is generated by the prefix key
1128 (typically
1129 .CW ALT
1130 or
1131 .CW Compose )
1132 followed by a double quote and a lower-case
1133 .CW u .
1134 When that character is read by the application, from the file
1135 .CW /dev/cons ,
1136 it is of course presented as its UTF encoding.
1137 Such sequences generate characters from an arbitrary set that
1138 includes all of Latin-1 plus a selection of mathematical
1139 and technical characters.
1140 An arbitrary Unicode character may be generated by typing the prefix,
1141 an upper case X, and four hexadecimal digits that identify
1142 the Unicode value.
1143 .PP
1144 These simple mechanisms are adequate for most of our day-to-day needs:
1145 it's easy to remember to type `ALT 1 2' for ½\^ or `ALT accent letter'
1146 for accented Latin letters.
1147 For the occasional unusual character, the cut and paste features of
1148 .CW 8½
1149 serve well.  A program called (perhaps misleadingly)
1150 .CW unicode
1151 takes as argument a hexadecimal value, and prints the UTF representation of that character,
1152 which may then be picked up with the mouse and used as input.
1153 .PP
1154 These methods
1155 are clearly unsatisfactory when working in a non-English language.
1156 In the native country of such a language
1157 the appropriate keyboard is likely to be at hand.
1158 But it's also reasonable\(emespecially now that the system handles Unicode characters\(emto
1159 work in a language foreign to the keyboard.
1160 .PP
1161 For alphabetic languages such as Greek or Russian, it is
1162 straightforward to construct a program that does phonetic substitution,
1163 so that, for example, typing a Latin `a' yields the Greek `α'.
1164 Within Plan 9, such a program can be inserted transparently
1165 between the real keyboard and a program such as the window system,
1166 providing a manageable input device for such languages.
1167 .PP
1168 For ideographic languages such as Chinese or Japanese the problem is harder.
1169 Native users of such languages have adopted methods for dealing with
1170 Latin keyboards that involve a hybrid technique based on phonetics
1171 to generate a list of possible symbols followed by menu selection to
1172 choose the desired one.
1173 Such methods can be
1174 effective, but their design must be rooted in information about
1175 the language unknown to non-native speakers.
1176 .CW Cxterm , (
1177 a Chinese terminal emulator built by and for
1178 Chinese programmers,
1179 employs such a technique
1180 [Pong and Zhang].)
1181 Although the technical problem of implementing such a device
1182 is easy in Plan 9\(emit is just an elaboration of the technique for
1183 alphabetic languages\(emour lack of familiarity with such languages
1184 has restrained our enthusiasm for building one.
1185 .PP
1186 The input problem is technically the least interesting but perhaps
1187 emotionally the most important of the problems of converting a system
1188 to an international character set.
1189 Beyond that remain the deeper problems of internationalization
1190 such as multi-lingual error messages and command names,
1191 problems we are not qualified to solve.
1192 With the ability to treat text of most languages on an equal
1193 footing, though, we can begin down that path.
1194 Perhaps people in non-English speaking countries will
1195 consider adopting Plan 9, solving the input problem locally\(emperhaps
1196 just by plugging in their local terminals\(emand begin to use
1197 a system with at least the capacity to be international.
1198 .SH
1199 Acknowledgements
1200 .PP
1201 Dennis Ritchie provided consultation and encouragement.
1202 Bob Flandrena converted most of the standard tools to UTF.
1203 Brian Kernighan suffered cheerfully with several
1204 inadequate implementations and converted
1205 .CW troff
1206 to UTF.
1207 Rich Drechsler converted his Postscript driver to UTF.
1208 John Hobby built the Postscript ☺.
1209 We thank them all.
1210 .SH
1211 References
1212 .LP
1213 [ANSIC] \f2American National Standard for Information Systems \-
1214 Programming Language C\f1, American National Standards Institute, Inc.,
1215 New York, 1990.
1216 .LP
1217 [ISO10646]
1218 ISO/IEC DIS 10646-1:1993
1219 \f2Information technology \-
1220 Universal Multiple-Octet Coded Character Set (UCS) \(em
1221 Part 1: Architecture and Basic Multilingual Plane\fP.
1222 .LP
1223 [Pike90] R. Pike, D. Presotto, K. Thompson, H. Trickey,
1224 ``Plan 9 from Bell Labs'',
1225 UKUUG Proc. of the Summer 1990 Conf.,
1226 London, England,
1227 1990.
1228 .LP
1229 [Pike91] R. Pike, ``8½, The Plan 9 Window System'', USENIX Summer
1230 Conf. Proc., Nashville, 1991, reprinted in this volume.
1231 .LP
1232 [Pike92] R. Pike, ``How to Use the Plan 9 C Compiler'', this volume.
1233 .LP
1234 [Pong and Zhang] Man-Chi Pong and Yongguang Zhang, ``cxterm:
1235 A Chinese Terminal Emulator for the X Window System'',
1236 .I
1237 Software\(emPractice and Experience,
1238 .R
1239 Vol 22(1), 809-926, October 1992.
1240 .LP
1241 [Unicode]
1242 \f2The Unicode Standard,
1243 Worldwide Character Encoding,
1244 Version 1.0, Volume 1\f1,
1245 The Unicode Consortium,
1246 Addison Wesley,
1247 New York,
1248 1991.