1\ extended characters (either 8bit or UTF-8, possibly other encodings) 2\ and their fixed-size variant 3 4\ Copyright (C) 2005,2006,2007 Free Software Foundation, Inc. 5 6\ This file is part of Gforth. 7 8\ Gforth is free software; you can redistribute it and/or 9\ modify it under the terms of the GNU General Public License 10\ as published by the Free Software Foundation, either version 3 11\ of the License, or (at your option) any later version. 12 13\ This program is distributed in the hope that it will be useful, 14\ but WITHOUT ANY WARRANTY; without even the implied warranty of 15\ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16\ GNU General Public License for more details. 17 18\ You should have received a copy of the GNU General Public License 19\ along with this program. If not, see http://www.gnu.org/licenses/. 20 21\ We can do some of these (and possibly faster) by just using the 22\ utf-8 words with an appropriate setting of max-single-byte, but I 23\ like to see how an 8bit setting without UTF-8 stuff looks like. 24 25Defer xemit ( xc -- ) \ xchar-ext 26\G Prints an xchar on the terminal. 27Defer xkey ( -- xc ) \ xchar-ext 28\G Reads an xchar from the terminal. This will discard all input 29\G events up to the completion of the xchar. 30Defer xchar+ ( xc-addr1 -- xc-addr2 ) \ xchar-ext 31\G Adds the size of the xchar stored at @var{xc-addr1} to this address, 32\G giving @var{xc-addr2}. 33Defer xchar- ( xc-addr1 -- xc-addr2 ) \ xchar-ext 34\G Goes backward from @var{xc_addr1} until it finds an xchar so that 35\G the size of this xchar added to @var{xc_addr2} gives 36\G @var{xc_addr1}. 37Defer +x/string ( xc-addr1 u1 -- xc-addr2 u2 ) \ xchar plus-x-slash-string 38\G Step forward by one xchar in the buffer defined by address 39\G @var{xc-addr1}, size @var{u1} pchars. @var{xc-addr2} is the address 40\G and u2 the size in pchars of the remaining buffer after stepping 41\G over the first xchar in the buffer. 42Defer x\string- ( xc-addr1 u1 -- xc-addr1 u2 ) \ xchar x-back-string-minus 43\G Step backward by one xchar in the buffer defined by address 44\G @var{xc-addr1} and size @var{u1} in pchars, starting at the end of 45\G the buffer. @var{xc-addr1} is the address and @var{u2} the size in 46\G pchars of the remaining buffer after stepping backward over the 47\G last xchar in the buffer. 48Defer xc@ ( xc-addr -- xc ) \ xchar-ext xc-fetch 49\G Fetchs the xchar @var{xc} at @var{xc-addr1}. 50Defer xc!+? ( xc xc-addr1 u1 -- xc-addr2 u2 f ) \ xchar-ext xc-store-plus-query 51\G Stores the xchar @var{xc} into the buffer starting at address 52\G @var{xc-addr1}, @var{u1} pchars large. @var{xc-addr2} points to the 53\G first memory location after @var{xc}, @var{u2} is the remaining 54\G size of the buffer. If the xchar @var{xc} did fit into the buffer, 55\G @var{f} is true, otherwise @var{f} is false, and @var{xc-addr2} 56\G @var{u2} equal @var{xc-addr1} @var{u1}. XC!+? is safe for buffer 57\G overflows, and therefore preferred over XC!+. 58Defer xc@+ ( xc-addr1 -- xc-addr2 xc ) \ xchar-ext xc-fetch-plus 59\G Fetchs the xchar @var{xc} at @var{xc-addr1}. @var{xc-addr2} points 60\G to the first memory location after @var{xc}. 61Defer xc-size ( xc -- u ) \ xchar-ext 62\G Computes the memory size of the xchar @var{xc} in pchars. 63Defer x-size ( xc-addr u1 -- u2 ) \ xchar 64\G Computes the memory size of the first xchar stored at @var{xc-addr} 65\G in pchars. 66Defer x-width ( xc-addr u -- n ) \ xchar-ext 67\G @var{n} is the number of monospace ASCII pchars that take the same 68\G space to display as the the xchar string starting at @var{xc-addr}, 69\G using @var{u} pchars; assuming a monospaced display font, 70\G i.e. pchar width is always an integer multiple of the width of an 71\G ASCII pchar. 72Defer -trailing-garbage ( xc-addr u1 -- addr u2 ) \ xchar-ext 73\G Examine the last XCHAR in the buffer @var{xc-addr} @var{u1}---if 74\G the encoding is correct and it repesents a full pchar, @var{u2} 75\G equals @var{u1}, otherwise, @var{u2} represents the string without 76\G the last (garbled) xchar. 77 78\ derived words, faster implementations are probably possible 79 80: x@+/string ( xc-addr1 u1 -- xc-addr2 u2 xc ) 81 \ !! check for errors? 82 over >r +x/string 83 r> xc@ ; 84 85: xhold ( xc -- ) 86 \G Put xc into the pictured numeric output 87 dup xc-size negate chars holdptr +! 88 holdptr @ dup holdbuf u< -&17 and throw 89 8 xc!+? 2drop drop ; 90 91\ fixed-size versions of these words 92 93: char- ( c-addr1 -- c-addr2 ) 94 [ 1 chars ] literal - ; 95 96: +string ( c-addr1 u1 -- c-addr2 u2 ) 97 1 /string ; 98: string- ( c-addr1 u1 -- c-addr1 u2 ) 99 1- ; 100 101: c!+? ( c c-addr1 u1 -- c-addr2 u2 f ) 102 dup 1 chars u< if \ or use < ? 103 rot drop false 104 else 105 >r dup >r c! 106 r> r> 1 /string true 107 then ; 108 109: c-size ( c -- 1 ) 110 drop 1 ; 111 112: set-encoding-fixed-width ( -- ) 113 ['] emit is xemit 114 ['] key is xkey 115 ['] char+ is xchar+ 116 ['] char- is xchar- 117 ['] +string is +x/string 118 ['] string- is x\string- 119 ['] c@ is xc@ 120 ['] c!+? is xc!+? 121 ['] count is xc@+ 122 ['] c-size is xc-size 123 ['] c-size is x-size 124 ['] nip IS x-width 125 ['] noop is -trailing-garbage 126; 127