Previous 199869 Revisions Next

r26171 Friday 15th November, 2013 at 09:27:03 UTC by Jürgen Buchmüller
Move string.h like functions to unicode.c; change comments to Doxygen/Qt style.
[/branches/alto2/src/emu/debug]debugvw.h dvdisasm.c dvtext.c textbuf.c
[/branches/alto2/src/lib/util]unicode.c unicode.h

branches/alto2/src/emu/debug/debugvw.h
r26170r26171
1919//  CONSTANTS
2020//**************************************************************************
2121
22// types passed to debug_view_manager::alloc_view()
22//! types passed to debug_view_manager::alloc_view()
2323enum debug_view_type
2424{
2525   DVT_NONE,
r26170r26171
3535};
3636
3737
38// notifications passed to view_notify()
38//! notifications passed to view_notify()
3939enum debug_view_notification
4040{
4141   VIEW_NOTIFY_NONE,
r26170r26171
4646
4747
4848// attribute bits for debug_view_char.attrib
49const UINT8 DCA_NORMAL      = 0x00;     // black on white
50const UINT8 DCA_CHANGED     = 0x01;     // red foreground
51const UINT8 DCA_SELECTED    = 0x02;     // light red background
52const UINT8 DCA_INVALID     = 0x04;     // dark blue foreground
53const UINT8 DCA_DISABLED    = 0x08;     // darker foreground
54const UINT8 DCA_ANCILLARY   = 0x10;     // grey background
55const UINT8 DCA_CURRENT     = 0x20;     // yellow background
56const UINT8 DCA_COMMENT     = 0x40;     // green foreground
57const UINT8 DCA_VISITED     = 0x80;     // light blue background
49const UINT8 DCA_NORMAL      = 0x00;     //!< black on white
50const UINT8 DCA_CHANGED     = 0x01;     //!< red foreground
51const UINT8 DCA_SELECTED    = 0x02;     //!< light red background
52const UINT8 DCA_INVALID     = 0x04;     //!< dark blue foreground
53const UINT8 DCA_DISABLED    = 0x08;     //!< darker foreground
54const UINT8 DCA_ANCILLARY   = 0x10;     //!< grey background
55const UINT8 DCA_CURRENT     = 0x20;     //!< yellow background
56const UINT8 DCA_COMMENT     = 0x40;     //!< green foreground
57const UINT8 DCA_VISITED     = 0x80;     //!< light blue background
5858
5959
6060// special characters that can be passed to process_char()
61const int DCH_UP            = 1;        // up arrow
62const int DCH_DOWN          = 2;        // down arrow
63const int DCH_LEFT          = 3;        // left arrow
64const int DCH_RIGHT         = 4;        // right arrow
65const int DCH_PUP           = 5;        // page up
66const int DCH_PDOWN         = 6;        // page down
67const int DCH_HOME          = 7;        // home
68const int DCH_CTRLHOME      = 8;        // ctrl+home
69const int DCH_END           = 9;        // end
70const int DCH_CTRLEND       = 10;       // ctrl+end
71const int DCH_CTRLRIGHT     = 11;       // ctrl+right
72const int DCH_CTRLLEFT      = 12;       // ctrl+left
61const int DCH_UP            = 1;        //!< up arrow
62const int DCH_DOWN          = 2;        //!< down arrow
63const int DCH_LEFT          = 3;        //!< left arrow
64const int DCH_RIGHT         = 4;        //!< right arrow
65const int DCH_PUP           = 5;        //!< page up
66const int DCH_PDOWN         = 6;        //!< page down
67const int DCH_HOME          = 7;        //!< home
68const int DCH_CTRLHOME      = 8;        //!< ctrl+home
69const int DCH_END           = 9;        //!< end
70const int DCH_CTRLEND       = 10;       //!< ctrl+end
71const int DCH_CTRLRIGHT     = 11;       //!< ctrl+right
72const int DCH_CTRLLEFT      = 12;       //!< ctrl+left
7373
7474
7575// special characters that can be passed to process_click()
76const int DCK_LEFT_CLICK    = 1;        // left instantaneous click
77const int DCK_RIGHT_CLICK   = 2;        // right instantaneous click
78const int DCK_MIDDLE_CLICK  = 3;        // middle instantaneous click
76const int DCK_LEFT_CLICK    = 1;        //!< left instantaneous click
77const int DCK_RIGHT_CLICK   = 2;        //!< right instantaneous click
78const int DCK_MIDDLE_CLICK  = 3;        //!< middle instantaneous click
7979
8080
8181//**************************************************************************
r26170r26171
8686class debug_view;
8787
8888
89// OSD callback function for a view
89//! OSD callback function for a view
9090typedef void (*debug_view_osd_update_func)(debug_view &view, void *osdprivate);
9191
9292
93// a single "character" in the debug view has an Unicode value and an attribute byte
93//! a single "character" in the debug view has an Unicode value and an attribute byte
9494struct debug_view_char
9595{
9696   unicode_char        uchar;
r26170r26171
9898};
9999
100100
101// pair of X,Y coordinates for sizing
101//! pair of X,Y coordinates for sizing
102102class debug_view_xy
103103{
104104public:
r26170r26171
109109};
110110
111111
112// debug_view_sources select from multiple sources available within a view
112//! debug_view_sources select from multiple sources available within a view
113113class debug_view_source
114114{
115115   DISABLE_COPYING(debug_view_source);
r26170r26171
129129
130130private:
131131   // internal state
132   debug_view_source *     m_next;                 // link to next item
133   astring                 m_name;                 // name of the source item
134   device_t *              m_device;               // associated device (if applicable)
135   bool                    m_is_octal;             // is view in octal or hex
132   debug_view_source *     m_next;                 //!< link to next item
133   astring                 m_name;                 //!< name of the source item
134   device_t *              m_device;               //!< associated device (if applicable)
135   bool                    m_is_octal;             //!< is view in octal or hex
136136};
137137
138138
r26170r26171
161161
162162private:
163163   // internal state
164   running_machine &       m_machine;              // reference to our machine
165   debug_view_source *     m_head;                 // head of the list
166   debug_view_source *     m_tail;                 // end of the tail
167   UINT32                  m_count;                // number of items in the list
164   running_machine &       m_machine;              //!< reference to our machine
165   debug_view_source *     m_head;                 //!< head of the list
166   debug_view_source *     m_tail;                 //!< end of the tail
167   UINT32                  m_count;                //!< number of items in the list
168168};
169169
170170
r26170r26171
223223
224224protected:
225225   // core view data
226   debug_view *            m_next;             // link to the next view
227   debug_view_type         m_type;             // type of view
228   const debug_view_source *m_source;          // currently selected data source
229   debug_view_source_list  m_source_list;      // list of available data sources
226   debug_view *            m_next;             //!< link to the next view
227   debug_view_type         m_type;             //!< type of view
228   const debug_view_source *m_source;          //!< currently selected data source
229   debug_view_source_list  m_source_list;      //!< list of available data sources
230230
231231   // OSD data
232   debug_view_osd_update_func m_osdupdate;     // callback for the update
233   void *                  m_osdprivate;       // OSD-managed private data
232   debug_view_osd_update_func m_osdupdate;     //!< callback for the update
233   void *                  m_osdprivate;       //!< OSD-managed private data
234234
235235   // visibility info
236   debug_view_xy           m_visible;          // visible size (in rows and columns)
237   debug_view_xy           m_total;            // total size (in rows and columns)
238   debug_view_xy           m_topleft;          // top-left visible position (in rows and columns)
239   debug_view_xy           m_cursor;           // cursor position
240   bool                    m_supports_cursor;  // does this view support a cursor?
241   bool                    m_cursor_visible;   // is the cursor visible?
236   debug_view_xy           m_visible;          //!< visible size (in rows and columns)
237   debug_view_xy           m_total;            //!< total size (in rows and columns)
238   debug_view_xy           m_topleft;          //!< top-left visible position (in rows and columns)
239   debug_view_xy           m_cursor;           //!< cursor position
240   bool                    m_supports_cursor;  //!< does this view support a cursor?
241   bool                    m_cursor_visible;   //!< is the cursor visible?
242242
243243   // update info
244   bool                    m_recompute;        // does this view require a recomputation?
245   UINT8                   m_update_level;     // update level; updates when this hits 0
246   bool                    m_update_pending;   // true if there is a pending update
247   bool                    m_osd_update_pending; // true if there is a pending update
248   debug_view_char *       m_viewdata;         // current array of view data
249   int                     m_viewdata_size;    // number of elements of the viewdata array
244   bool                    m_recompute;        //!< does this view require a recomputation?
245   UINT8                   m_update_level;     //!< update level; updates when this hits 0
246   bool                    m_update_pending;   //!< true if there is a pending update
247   bool                    m_osd_update_pending; //!< true if there is a pending update
248   debug_view_char *       m_viewdata;         //!< current array of view data
249   int                     m_viewdata_size;    //!< number of elements of the viewdata array
250250
251251private:
252   running_machine &       m_machine;          // machine associated with this view
252   running_machine &       m_machine;          //!< machine associated with this view
253253};
254254
255255
r26170r26171
277277   debug_view *append(debug_view *view);
278278
279279   // internal state
280   running_machine &   m_machine;              // reference to our machine
281   debug_view *        m_viewlist;             // list of views
280   running_machine &   m_machine;              //!< reference to our machine
281   debug_view *        m_viewlist;             //!< list of views
282282};
283283
284284
r26170r26171
308308   bool recompute();
309309
310310   // internal state
311   running_machine &   m_machine;              // reference to the machine
312   bool                m_dirty;                // true if the expression needs to be re-evaluated
313   UINT64              m_result;               // last result from the expression
314   parsed_expression   m_parsed;               // parsed expression data
315   astring             m_string;               // copy of the expression string
311   running_machine &   m_machine;              //!< reference to the machine
312   bool                m_dirty;                //!< true if the expression needs to be re-evaluated
313   UINT64              m_result;               //!< last result from the expression
314   parsed_expression   m_parsed;               //!< parsed expression data
315   astring             m_string;               //!< copy of the expression string
316316};
317317
318318
branches/alto2/src/emu/debug/dvdisasm.c
r26170r26171
1717#define   DISASM_BUFFSIZE   128
1818
1919//**************************************************************************
20//  UNICODE HELPERS
21//**************************************************************************
22static int unicode_strlen(const unicode_char* src)
23{
24   int len = 0;
25   while (*src++)
26      len++;
27   return len;
28}
29
30static int unicode_strncmp(const unicode_char* dst, const unicode_char* src, size_t len)
31{
32   while (*src && *dst && *src == *dst && len > 0) {
33      src++;
34      dst++;
35      len--;
36   }
37   if (*src != *dst)
38      return *src < *dst ? -1 : +1;
39   return 0;
40}
41
42static int unicode_sprintf(unicode_char* dst, const char* format, ...)
43{
44   va_list ap;
45   char buff[256];
46   va_start(ap, format);
47   int len = vsnprintf(buff, sizeof(buff), format, ap);
48   va_end(ap);
49   for (int i = 0; i < len; i++)
50      *dst++ = buff[i];
51   *dst = 0;
52   return len;
53}
54
55static unicode_char* unicode_strncpy(unicode_char* dst, const unicode_char* src, size_t len)
56{
57   unicode_char* str = dst;
58   while (*src && len > 0) {
59      *dst++ = *src++;
60      len--;
61   }
62   if (len > 0)
63      *dst = 0;
64   return str;
65}
66
67//**************************************************************************
6820//  DEBUG VIEW DISASM SOURCE
6921//**************************************************************************
7022
r26170r26171
439391      unicode_char *destbuf = &m_dasm[instr * m_allocated.x];
440392      unicode_char oldbuf[DISASM_BUFFSIZE];
441393      if (lines == 1)
442         unicode_strncpy(oldbuf, destbuf, MIN(DISASM_BUFFSIZE, m_allocated.x));
394         uchar_strncpy(oldbuf, destbuf, MIN(DISASM_BUFFSIZE, m_allocated.x));
443395
444396      // convert back and set the address of this instruction
445397      m_byteaddress[instr] = pcbyte;
446      unicode_sprintf(&destbuf[0], " %s  ", core_i64_format(source.m_space.byte_to_address(pcbyte), source.m_space.logaddrchars()/2*char_num, source.is_octal()));
398      uchar_sprintf(&destbuf[0], " %s  ", core_i64_format(source.m_space.byte_to_address(pcbyte), source.m_space.logaddrchars()/2*char_num, source.is_octal()));
447399
448400      // make sure we can translate the address, and then disassemble the result
449401      char buffer[DISASM_BUFFSIZE];
r26170r26171
484436         // get the bytes
485437         numbytes = source.m_space.address_to_byte(numbytes) & source.m_space.logbytemask();
486438         generate_bytes(pcbyte, numbytes, minbytes, buffer, m_allocated.x - m_divider2, m_right_column == DASM_RIGHTCOL_ENCRYPTED);
487         unicode_sprintf(&destbuf[m_divider2], "%s", buffer);
439         uchar_sprintf(&destbuf[m_divider2], "%s", buffer);
488440      }
489441      else if (m_right_column == DASM_RIGHTCOL_COMMENTS)
490442      {
r26170r26171
492444         offs_t comment_address = source.m_space.byte_to_address(m_byteaddress[instr]);
493445         const char *text = source.m_device.debug()->comment_text(comment_address);
494446         if (text != NULL)
495            unicode_sprintf(&destbuf[m_divider2], "// %.*s", m_allocated.x - m_divider2 - 1, text);
447            uchar_sprintf(&destbuf[m_divider2], "// %.*s", m_allocated.x - m_divider2 - 1, text);
496448      }
497449
498450      // see if the line changed at all
499      if (lines == 1 && unicode_strncmp(oldbuf, destbuf, MIN(DISASM_BUFFSIZE, m_allocated.x)) != 0)
451      if (lines == 1 && uchar_strncmp(oldbuf, destbuf, MIN(DISASM_BUFFSIZE, m_allocated.x)) != 0)
500452         changed = true;
501453   }
502454
r26170r26171
645597
646598         // get the effective string
647599         const unicode_char *data = &m_dasm[effrow * m_allocated.x];
648         UINT32 len = unicode_strlen(data);
600         UINT32 len = uchar_strlen(data);
649601
650602         // copy data
651603         UINT32 effcol = m_topleft.x;
branches/alto2/src/emu/debug/dvtext.c
r26170r26171
1515
1616
1717//**************************************************************************
18//  UNICODE HELPERS
19//**************************************************************************
20static int unicode_strlen(const unicode_char* src)
21{
22   int len = 0;
23   while (*src++)
24      len++;
25   return len;
26}
27
28
29//**************************************************************************
3018//  DEBUG VIEW TEXTBUF
3119//**************************************************************************
3220
r26170r26171
9280      // if this visible row is valid, add it to the buffer
9381      if (line != NULL)
9482      {
95         size_t len = unicode_strlen(line);
83         size_t len = uchar_strlen(line);
9684         UINT32 effcol = m_topleft.x;
9785
9886         // copy data
branches/alto2/src/emu/debug/textbuf.c
r26170r26171
4646***************************************************************************/
4747
4848/*-------------------------------------------------
49   utf8_strlen - return the number of unicode
50   characters in UTF-8 encoded string
51-------------------------------------------------*/
52INLINE int utf8_strlen(const char* src)
53{
54   int total = 0;
55   while (*src) {
56      unicode_char uchar;
57      int len = uchar_from_utf8(&uchar, src, strlen(src));
58      if (len < 0)
59         break;   // invalid UTF-8
60      total++;
61      src += len;
62   }
63   return total;
64}
65
66/*-------------------------------------------------
6749   buffer_used - return the number of bytes
6850   currently held in the buffer
6951-------------------------------------------------*/
branches/alto2/src/lib/util/unicode.c
r26170r26171
11// license:BSD-3-Clause
2// copyright-holders:Aaron Giles
2// copyright-holders:Aaron Giles, Jürgen Buchmüller
33/*********************************************************************
44
55   unicode.c
r26170r26171
1111#include "unicode.h"
1212
1313
14/*-------------------------------------------------
15   uchar_isvalid - return true if a given
16   character is a legitimate unicode character
17-------------------------------------------------*/
18
14/**
15 * @brief test for legitimate unicode values
16 *
17 * return true if a given character is a legitimate unicode character
18 *
19 * @param uchar value to inspect
20 * @return non zero (true) if uchar is valid, 0 otherwise
21 */
1922int uchar_isvalid(unicode_char uchar)
2023{
2124   return (uchar < 0x110000) && !((uchar >= 0xd800) && (uchar <= 0xdfff));
2225}
2326
2427
25/*-------------------------------------------------
26   uchar_from_utf8 - convert a UTF-8 sequence
27   into a unicode character
28-------------------------------------------------*/
29
28/**
29 * @brief convert an UTF-8 sequence into an unicode character
30 * @param uchar pointer to the resulting unicode_char
31 * @param utf8char pointer to the source string (may be NULL)
32 * @param count number of characters available in utf8char
33 * @return the number of characters used
34 */
3035int uchar_from_utf8(unicode_char *uchar, const char *utf8char, size_t count)
3136{
3237   unicode_char c, minchar;
r26170r26171
117122}
118123
119124
120/*-------------------------------------------------
121   uchar_from_utf16 - convert a UTF-16 sequence
122   into a unicode character
123-------------------------------------------------*/
124
125/**
126 * @brief convert a UTF-16 sequence   into an unicode character
127 * @param uchar pointer to the resulting unicode_char
128 * @param utf16char pointer to the source string (may be NULL)
129 * @param count number of characters available in utf16char
130 * @return the number of characters used
131 */
125132int uchar_from_utf16(unicode_char *uchar, const utf16_char *utf16char, size_t count)
126133{
127134   int rc = -1;
r26170r26171
151158}
152159
153160
154/*-------------------------------------------------
155   uchar_from_utf16f - convert a UTF-16 sequence
156   into a unicode character from a flipped
157   byte order
158-------------------------------------------------*/
159
161/**
162 * @brief convert a UTF-16 sequence   into an unicode character from a flipped byte order
163 *
164 * This flips endianness of the first two utf16_char in a local
165 * copy and then calls uchar_from_utf16.
166 *
167 * @param uchar pointer to the resulting unicode_char
168 * @param utf16char pointer to the source string (may be NULL)
169 * @param count number of characters available in utf16char
170 * @return the number of characters used
171 */
160172int uchar_from_utf16f(unicode_char *uchar, const utf16_char *utf16char, size_t count)
161173{
162174   utf16_char buf[2] = {0};
r26170r26171
168180}
169181
170182
171/*-------------------------------------------------
172   utf8_from_uchar - convert a unicode character
173   into a UTF-8 sequence
174-------------------------------------------------*/
175
183/**
184 * @brief convert an unicode character into a UTF-8 sequence
185 * @param utf8string pointer to the result char array
186 * @param count number of characters that can be written to utf8string
187 * @param uchar unciode_char value to convert
188 * @return -1 on error, or the number of chars written on success (1 to 6)
189 */
176190int utf8_from_uchar(char *utf8string, size_t count, unicode_char uchar)
177191{
178192   int rc = 0;
r26170r26171
245259   return rc;
246260}
247261
248
249/*-------------------------------------------------
250   utf16_from_uchar - convert a unicode character
251   into a UTF-16 sequence
252-------------------------------------------------*/
253
262/**
263 * @brief convert an unicode character into a UTF-16 sequence
264 * @param utf16string pointer to the result array of utf16_char
265 * @param count number of characters that can be written to utf16string
266 * @param uchar unciode_char value to convert
267 * @return -1 on error, or the number of utf16_char written on success (1 or 2)
268 */
254269int utf16_from_uchar(utf16_char *utf16string, size_t count, unicode_char uchar)
255270{
256271   int rc;
r26170r26171
282297   return rc;
283298}
284299
285
286/*-------------------------------------------------
287   utf16_from_uchar - convert a unicode character
288   into a UTF-16 sequence with flipped endianness
289-------------------------------------------------*/
290
300/**
301 * @brief convert an unicode character into a UTF-16 sequence with flipped endianness
302 * @param utf16string pointer to the result array of utf16_char
303 * @param count number of characters that can be written to utf16string
304 * @param uchar unciode_char value to convert
305 * @return -1 on error, or the number of utf16_char written on success (1 or 2)
306 */
291307int utf16f_from_uchar(utf16_char *utf16string, size_t count, unicode_char uchar)
292308{
293309   int rc;
294310   utf16_char buf[2] = { 0, 0 };
295311
296   rc = utf16_from_uchar(buf, count, uchar);
312   rc = utf16_from_uchar(buf, 2, uchar);
297313
298   if (rc >= 1)
314   if (rc >= 1 && count >= 1)
299315      utf16string[0] = FLIPENDIAN_INT16(buf[0]);
300   if (rc >= 2)
316   if (rc >= 2 && count >= 2)
301317      utf16string[1] = FLIPENDIAN_INT16(buf[1]);
302   return rc;
318   return rc < count ? rc : count;
303319}
304320
305321
306/*-------------------------------------------------
307   utf8_previous_char - return a pointer to the
308   previous character in a string
309-------------------------------------------------*/
310
322/**
323 * @brief return a pointer to the previous character in a string
324 * @param utf8string const pointer to the starting position in the string
325 * @return pointer to the character which is not an UTF-8 auxiliary character
326 */
311327const char *utf8_previous_char(const char *utf8string)
312328{
313329   while ((*--utf8string & 0xc0) == 0x80)
r26170r26171
315331   return utf8string;
316332}
317333
318
319/*-------------------------------------------------
320   utf8_is_valid_string - return true if the
321   given string is a properly formed sequence of
322   UTF-8 characters
323-------------------------------------------------*/
324
334/**
335 * @brief return true if the given string is a properly formed sequence of UTF-8 characters
336 * @param utf8string const pointer to the source string
337 * @return TRUE if the string is valid, FALSE otherwise
338 */
325339int utf8_is_valid_string(const char *utf8string)
326340{
327341   int remaining_length = strlen(utf8string);
r26170r26171
344358   return TRUE;
345359}
346360
347/*-------------------------------------------------
348   unicode_load_table - load a lookup table
349   for e.g. ISO-8859-1 to Unicode from a file
350   The expected format is "Format A" defined
351   by unicode.org
352-------------------------------------------------*/
361/**
362 * @brief return the number of decoded Unicode values in UTF-8 encoded string
363 * @param src pointer to the array of UTF-8 encoded characters
364 * @return number of unicode_char values decoded from the UTF-8 string
365 */
366size_t utf8_strlen(const char* src)
367{
368   int total = 0;
369   while (*src) {
370      unicode_char uchar;
371      int len = uchar_from_utf8(&uchar, src, strlen(src));
372      if (len < 0)
373         break;   // invalid UTF-8
374      total++;
375      src += len;
376   }
377   return total;
378}
379
380/**
381 * @brief load a lookup table 8 bit codes to Unicode values
382 *
383 * This opens and reads a file %name which has to be in the
384 * unicode.org defined "Format A".
385 * That is three columns
386 *   column 1: hex encoded 8 bit value of the code
387 *   column 2: hex encoded 32 bit (max) unicode value
388 *   column 3: a hash (#) and optional comment until the end-of-line
389 *
390 * @param name name of the (text) file to parse
391 * @return pointer to a newly allocated array of 256 unicode_char values
392 */
353393unicode_char * uchar_table_load(const char* name)
354394{
355395   FILE* file = fopen(name, "r");
r26170r26171
384424   return table;
385425}
386426
427/**
428 * @brief return the 8 bit code that is mapped to the specified unicode_char
429 * @param table table of 256 unicode_char values to use for the reverse lookup
430 * @param uchar unicode value to revers lookup
431 * @return UINT8 with the 8 bit code, or 255 if uchar wasn't found
432 */
387433UINT8 uchar_table_index(unicode_char* table, unicode_char uchar)
388434{
389435   UINT8 index;
r26170r26171
393439   return index;
394440}
395441
442/**
443 * @brief free an unicode lookup table
444 * @param table
445 */
396446void uchar_table_free(unicode_char* table)
397447{
398448   if (table)
399449      free(table);
400450}
401451
452/**
453 * @brief return the unicode_char array length
454 * @param src pointer to an array of unicode_char
455 * @return length of the array until the first 0
456 */
457size_t uchar_strlen(const unicode_char* src)
458{
459   int len = 0;
460   while (*src++)
461      len++;
462   return len;
463}
464
465/**
466 * @brief compare two unicode_char arrays
467 * @param dst pointer to the first array of unicode_char
468 * @param src pointer to the second array of unicode_char
469 * @return 0 if dst == src, -1 if dst < src or +1 otherwise
470 */
471int uchar_strcmp(const unicode_char* dst, const unicode_char* src)
472{
473   while (*src && *dst && *src == *dst)
474   {
475      src++;
476      dst++;
477   }
478   if (*src != *dst)
479      return *src < *dst ? -1 : +1;
480   return 0;
481}
482
483/**
484 * @brief compare two unicode_char arrays with length limiting
485 * @param dst pointer to the first array of unicode_char
486 * @param src pointer to the second array of unicode_char
487 * @param len maximum number of unicode_char to compare
488 * @return 0 if dst == src, -1 if dst < src or +1 otherwise
489 */
490int uchar_strncmp(const unicode_char* dst, const unicode_char* src, size_t len)
491{
492   while (*src && *dst && *src == *dst && len > 0)
493   {
494      src++;
495      dst++;
496      len--;
497   }
498   if (*src != *dst)
499      return *src < *dst ? -1 : +1;
500   return 0;
501}
502
503/**
504 * @brief print a formatted string of ASCII characters to an unicode_char array
505 * @param dst pointer to the array
506 * @param format format string followed by optional parameters
507 * @return number of unicode_char stored in dst
508 */
509int uchar_sprintf(unicode_char* dst, const char* format, ...)
510{
511   va_list ap;
512   char buff[256];
513   va_start(ap, format);
514   int len = vsnprintf(buff, sizeof(buff), format, ap);
515   va_end(ap);
516   for (int i = 0; i < len; i++)
517      *dst++ = buff[i];
518   *dst = 0;
519   return len;
520}
521
522/**
523 * @brief copy an array of unicode_char from source to destination
524 *
525 * @param dst pointer to destination array
526 * @param src const pointer to the source array
527 * @return a pointer to the original destination
528 */
529unicode_char* uchar_strcpy(unicode_char* dst, const unicode_char* src)
530{
531   unicode_char* str = dst;
532   while (*src)
533      *dst++ = *src++;
534   return str;
535}
536
537/**
538 * @brief copy a length limited array of unicode_char from source to destination
539 *
540 * This function always terminates dst with a 0 unicode_char, unlike some
541 * classic libc implementations of strncpy(). This means that actually at
542 * most len-1 unicode_char are copied from src to leave room for the 0 code.
543 *
544 * @param dst pointer to destination array
545 * @param src const pointer to the source array
546 * @param len maximum number of unicode_char to copy
547 * @return a pointer to the original destination
548 */
549unicode_char* uchar_strncpy(unicode_char* dst, const unicode_char* src, size_t len)
550{
551   unicode_char* str = dst;
552   while (*src && len > 1)
553   {
554      *dst++ = *src++;
555      len--;
556   }
557   if (len > 0)
558      *dst = 0;
559   return str;
560}
561
402562/***************************************************************************
403563 *
404564 * Parsing and access to the UnicodeData table published at unicode.org
405565 *
406566 ***************************************************************************/
407567
408//! Information about a unicode_char
568//! Information about an unicode_char
409569typedef struct {
410570#if   NEED_UNICODE_NAME
411571   char *name;                           //!< name of the character
r26170r26171
552712   {0xfe70, 0xfeff, "Arabic Presentation Forms-B"},
553713   {0xff00, 0xffef, "Halfwidth and Fullwidth Forms"},
554714   {0xfff0, 0xffff, "Specials"}
715   // FIXME: add ranges for the Unicode planes 1 to 16
555716};
556717#endif
557718
558719#if   NEED_UNICODE_CCOM
559720static const char *canonical_combining_str(UINT8 val)
560721{
561   switch (val) {
722   switch (val)
723   {
562724   case 0:      return "Spacing, split, enclosing, reordrant, and Tibetan subjoined";
563725   case 1:      return "Overlays and interior";
564726   case 7:      return "Nuktas";
r26170r26171
620782{
621783   if (!unicode_data || uchar >= UNICODE_PLANESIZE || !unicode_data[uchar])
622784      return "";
623   switch (unicode_data[uchar]->gen_cat) {
785   switch (unicode_data[uchar]->gen_cat)
786   {
624787   case gcat_Lu:   return "Lu: Letter, Uppercase";
625788   case gcat_Ll:   return "Ll: Letter, Lowercase";
626789   case gcat_Lt:   return "Lt: Letter, Titlecase";
r26170r26171
685848{
686849   if (!unicode_data || uchar >= UNICODE_PLANESIZE || !unicode_data[uchar])
687850      return "";
688   switch (unicode_data[uchar]->bidi) {
851   switch (unicode_data[uchar]->bidi)
852   {
689853   case bidi_L:   return "L: Left-to-Right";
690854   case bidi_LRE:   return "LRE: Left-to-Right Embedding";
691855   case bidi_LRO:   return "LRO: Left-to-Right Override";
r26170r26171
723887{
724888   if (!unicode_data || uchar >= UNICODE_PLANESIZE || !unicode_data[uchar])
725889      return "";
726   switch (unicode_data[uchar]->decomp_map) {
890   switch (unicode_data[uchar]->decomp_map)
891   {
727892   case deco_canonical:   return "Canonical mapping";
728893   case deco_font:         return "A font variant (e.g. a blackletter form)";
729894   case deco_noBreak:      return "A no-break version of a space or hyphen";
r26170r26171
9151080   static UINT32 hit = 0;
9161081   UINT32 i;
9171082
918   for (i = hit; i < sizeof(unicode_ranges)/sizeof(unicode_ranges[0]); i++) {
919      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last) {
1083   for (i = hit; i < sizeof(unicode_ranges)/sizeof(unicode_ranges[0]); i++)
1084   {
1085      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last)
1086      {
9201087         hit = i;
9211088         return unicode_ranges[i].name;
9221089      }
9231090   }
924   for (i = 0; i < hit; i++) {
925      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last) {
1091   for (i = 0; i < hit; i++)
1092   {
1093      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last)
1094      {
9261095         hit = i;
9271096         return unicode_ranges[i].name;
9281097      }
r26170r26171
9361105   static UINT32 hit = 0;
9371106   UINT32 i;
9381107
939   for (i = hit; i < sizeof(unicode_ranges)/sizeof(unicode_ranges[0]); i++) {
940      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last) {
1108   for (i = hit; i < sizeof(unicode_ranges)/sizeof(unicode_ranges[0]); i++)
1109   {
1110      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last)
1111      {
9411112         hit = i;
9421113         return unicode_ranges[i].first;
9431114      }
9441115   }
945
946   for (i = 0; i < hit; i++) {
947      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last) {
1116   for (i = 0; i < hit; i++)
1117   {
1118      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last)
1119      {
9481120         hit = i;
9491121         return unicode_ranges[i].first;
9501122      }
r26170r26171
9581130   static UINT32 hit = 0;
9591131   UINT32 i;
9601132
961   for (i = hit; i < sizeof(unicode_ranges)/sizeof(unicode_ranges[0]); i++) {
962      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last) {
1133   for (i = hit; i < sizeof(unicode_ranges)/sizeof(unicode_ranges[0]); i++)
1134   {
1135      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last)
1136      {
9631137         hit = i;
9641138         return unicode_ranges[i].last;
9651139      }
9661140   }
967
968   for (i = 0; i < hit; i++) {
969      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last) {
1141   for (i = 0; i < hit; i++)
1142   {
1143      if (unicode_ranges[i].first <= uchar && uchar <= unicode_ranges[i].last)
1144      {
9701145         hit = i;
9711146         return unicode_ranges[i].last;
9721147      }
r26170r26171
9851160   if (src)
9861161      token = src;
9871162   start = token;
988   while (token && *token) {
1163   while (token && *token)
1164   {
9891165      const char *d = delim;
990      while (*d) {
991         if (*token == *d) {
1166      while (*d)
1167      {
1168         if (*token == *d)
1169         {
9921170            *token++ = '\0';
9931171            return start;
9941172         }
r26170r26171
10161194   unicode_char first = 0;
10171195   unicode_char last = 0;
10181196
1019   while (fgets(line, 1024, file)) {
1197   while (fgets(line, 1024, file))
1198   {
10201199      unicode_data_t u;
10211200      unicode_char code;
10221201      int tokennum = 1;
r26170r26171
10341213      tokennum++;
10351214      if (NULL == (token = parse_strtok(NULL, ";\r\n")))
10361215         fprintf(stderr, "%s: token #%d failed on line %d\n%s", __FUNCTION__, tokennum, linenum, line);
1037      if (NULL != token) {
1216      if (NULL != token)
1217      {
10381218         // check for a range description
1039         if (token[0] == '<') {
1219         if (token[0] == '<')
1220         {
10401221            // strip a trailing ", First>" string fragment
1041            if (0 == strcmp(token + strlen(token) - 8,", First>")) {
1222            if (0 == strcmp(token + strlen(token) - 8,", First>"))
1223            {
10421224               strcpy(token, token + 1);
10431225               token[strlen(token) - 8] = '\0';
10441226               first = code;
10451227            }
10461228            // strip a trailing ", Last>" string fragment
1047            if (0 == strcmp(token + strlen(token) - 7,", Last>")) {
1229            if (0 == strcmp(token + strlen(token) - 7,", Last>"))
1230            {
10481231               strcpy(token, token + 1);
10491232               token[strlen(token) - 7] = '\0';
10501233               last = code;
r26170r26171
10621245#if   NEED_UNICODE_GCAT
10631246      // parse general category
10641247      u.gen_cat = gcat_0;
1065      if (NULL != token) {
1248      if (NULL != token)
1249      {
10661250         if (0 == strcmp(token, "Lu"))
10671251            u.gen_cat = gcat_Lu;
10681252         if (0 == strcmp(token, "Ll"))
r26170r26171
11401324#if   NEED_UNICODE_BIDI
11411325      // parse bidirectional category
11421326      u.bidi = bidi_0;
1143      if (NULL != token) {
1327      if (NULL != token)
1328      {
11441329         if (0 == strcmp(token, "L"))
11451330            u.bidi = bidi_L;   // Left-to-Right
11461331         if (0 == strcmp(token, "LRE"))
r26170r26171
11871372         fprintf(stderr, "%s: token #%d failed on line %d\n%s", __FUNCTION__, tokennum, linenum, line);
11881373#if   NEED_UNICODE_DECO
11891374      // parse decomposition mapping
1190      if (NULL != token) {
1375      if (NULL != token)
1376      {
11911377         unicode_char decomposed[256];
11921378         UINT8 n = 0;
11931379         char *p = token;
r26170r26171
12291415            while (isspace(*p))
12301416               p++;
12311417         // parse decomposition codes
1232         while (*p) {
1418         while (*p)
1419         {
12331420            // skip initial whitespace
12341421            while (isspace(*p))
12351422               p++;
r26170r26171
12421429            if (n >= 255)
12431430               break;
12441431         }
1245         if (n > 0) {
1432         if (n > 0)
1433         {
12461434            u.n_decomp = n;
12471435            u.decomp_codes = (unicode_char*)malloc(sizeof(unicode_char) * n);
12481436            memcpy(u.decomp_codes, decomposed, sizeof(unicode_char) * n);
r26170r26171
12961484      tokennum++;
12971485      if (NULL == (token = parse_strtok(NULL, ";\r\n")))
12981486         fprintf(stderr, "%s: token #%d failed on line %d\n%s", __FUNCTION__, tokennum, linenum, line);
1299      if (NULL != token && *token) {
1487      if (NULL != token && *token)
1488      {
13001489         /* FIXME: hmm ... don't know what this token means */
13011490      }
13021491
r26170r26171
13241513         u.titlecase = strtoul(token, NULL, 16);
13251514#endif
13261515
1327      if (first > 0 && last > 0) {
1328         if (first + 1 >= UNICODE_PLANESIZE) {
1516      if (first > 0 && last > 0)
1517      {
1518         if (first + 1 >= UNICODE_PLANESIZE)
1519         {
13291520            fprintf(stderr, "%s: range %#07x-%#07x outside planes\n", __FUNCTION__, first + 1, last);
1330         } else {
1521         }
1522         else
1523         {
13311524            for (code = first + 1; code <= last && code < UNICODE_PLANESIZE; code++)
13321525               unicode_data[code] = unicode_data[first];
13331526         }
r26170r26171
13351528         last = 0;
13361529         code = UNICODE_PLANESIZE;
13371530      }
1338      if (code < UNICODE_PLANESIZE) {
1531      if (code < UNICODE_PLANESIZE)
1532      {
13391533         unicode_data[code] = (unicode_data_t *)malloc(sizeof(unicode_data_t));
13401534         memcpy(unicode_data[code], &u, sizeof(u));
13411535      }
branches/alto2/src/lib/util/unicode.h
r26170r26171
2222
2323#include <stdlib.h>
2424#include <stdio.h>
25#include <stdarg.h>
2526#include <ctype.h>
2627#include "osdcore.h"
2728
r26170r26171
3132   CONSTANTS
3233***************************************************************************/
3334
34/* these defines specify the maximum size of different types of Unicode
35 * character encodings */
36#define UTF8_CHAR_MAX   6
37#define UTF16_CHAR_MAX  2
38
39/* these are UTF-8 encoded strings for common characters */
40#define UTF8_NBSP           "\xc2\xa0"          /* non-breaking space */
41#define UTF8_MULTIPLY       "\xc3\x97"          /* multiplication symbol */
42#define UTF8_DEGREES        "\xc2\xb0"          /* degrees symbol */
43
44#define a_RING              "\xc3\xa5"          /* small a with a ring */
45#define a_UMLAUT            "\xc3\xa4"          /* small a with an umlaut */
46#define o_UMLAUT            "\xc3\xb6"          /* small o with an umlaut */
47#define u_UMLAUT            "\xc3\xbc"          /* small u with an umlaut */
48#define e_ACUTE             "\xc3\xa9"          /* small e with an acute */
49
50#define A_RING              "\xc3\x85"          /* capital A with a ring */
51#define A_UMLAUT            "\xc3\x84"          /* capital A with an umlaut */
52#define O_UMLAUT            "\xc3\x96"          /* capital O with an umlaut */
53#define U_UMLAUT            "\xc3\x9c"          /* capital U with an umlaut */
54#define E_ACUTE             "\xc3\x89"          /* capital E with an acute */
55
56#define UTF8_LEFT           "\xe2\x86\x90"      /* cursor left */
57#define UTF8_RIGHT          "\xe2\x86\x92"      /* cursor right */
58#define UTF8_UP             "\xe2\x86\x91"      /* cursor up */
59#define UTF8_DOWN           "\xe2\x86\x93"      /* cursor down */
60
61
62
63/***************************************************************************
64   TYPE DEFINITIONS
65***************************************************************************/
66
67typedef UINT16 utf16_char;
68typedef UINT32 unicode_char;
69
70
71
72/***************************************************************************
73   FUNCTION PROTOTYPES
74***************************************************************************/
75
76/* tests to see if a unicode char is a valid code point */
77int uchar_isvalid(unicode_char uchar);
78
79/* converting strings to 32-bit Unicode chars */
80int uchar_from_utf8(unicode_char *uchar, const char *utf8char, size_t count);
81int uchar_from_utf16(unicode_char *uchar, const utf16_char *utf16char, size_t count);
82int uchar_from_utf16f(unicode_char *uchar, const utf16_char *utf16char, size_t count);
83
84/* converting 32-bit Unicode chars to strings */
85int utf8_from_uchar(char *utf8string, size_t count, unicode_char uchar);
86int utf16_from_uchar(utf16_char *utf16string, size_t count, unicode_char uchar);
87int utf16f_from_uchar(utf16_char *utf16string, size_t count, unicode_char uchar);
88
89/* misc UTF-8 helpers */
90const char *utf8_previous_char(const char *utf8string);
91int utf8_is_valid_string(const char *utf8string);
92
93/* Unicode lookup table loader */
94//! load a table translating UINT8 (unsigned char) to Unicode values
95unicode_char * uchar_table_load(const char* name);
96
97//! reverse lookup of uchar in a Unicode table - returns 255 if not found
98UINT8 uchar_table_index(unicode_char* table, unicode_char uchar);
99
100//! free a unicode table
101void uchar_table_free(unicode_char* table);
102
103/***************************************************************************
104 *   unicode.org published UnicodeData.txt
105 *  parser and accessors
106 ***************************************************************************/
107
108//! load the UnicodeData.txt file an parse it
109int unicode_data_load(const char* name);
110
111//! free the UnicodeData.txt table memory
112void unicode_data_free();
113
11435//! size of the first 17 Unicode planes
11536#define   UNICODE_PLANESIZE      0x110000
11637
11738#ifndef   NEED_UNICODE_RANGES
11839#define   NEED_UNICODE_RANGES      1      //!< define to 1, if the name, first or last of the range of a code is needed
11940#endif
120
12141#ifndef   NEED_UNICODE_NAME
12242#define   NEED_UNICODE_NAME      1      //!< define to 1, if the name of a code is needed
12343#endif
124
12544#ifndef   NEED_UNICODE_NAME10
12645#define   NEED_UNICODE_NAME10      1      //!< define to 1, if the short name of a code is needed
12746#endif
128
12947#ifndef   NEED_UNICODE_GCAT
13048#define   NEED_UNICODE_GCAT      1      //!< define to 1, if the general category of a code is needed
13149#endif
132
13350#ifndef   NEED_UNICODE_CCOM
13451#define   NEED_UNICODE_CCOM      1      //!< define to 1, if the canonical combining (name) of a code is needed
13552#endif
136
13753#ifndef   NEED_UNICODE_BIDI
13854#define   NEED_UNICODE_BIDI      1      //!< define to 1, if the bidirectional category of a code is needed
13955#endif
140
14156#ifndef   NEED_UNICODE_DECO
14257#define   NEED_UNICODE_DECO      1      //!< define to 1, if the decomposition codes of a code are needed
14358#endif
144
14559#ifndef   NEED_UNICODE_DECIMAL
14660#define   NEED_UNICODE_DECIMAL   1      //!< define to 1, if the decimal value of a code is needed
14761#endif
148
14962#ifndef   NEED_UNICODE_DIGIT
15063#define   NEED_UNICODE_DIGIT      1      //!< define to 1, if the digit value of a code is needed
15164#endif
152
15365#ifndef   NEED_UNICODE_NUMERIC
15466#define   NEED_UNICODE_NUMERIC   1      //!< define to 1, if the numeric value of a code is needed
15567#endif
156
15768#ifndef   NEED_UNICODE_MIRRORED
15869#define   NEED_UNICODE_MIRRORED   1      //!< define to 1, if the mirrored flag of a code is needed
15970#endif
160
16171#ifndef   NEED_UNICODE_DECN
16272#define   NEED_UNICODE_DECN      1      //!< define to 1, if access to decomposed code [n] of a code is needed
16373#endif
164
16574#ifndef   NEED_UNICODE_UCASE
16675#define   NEED_UNICODE_UCASE      1      //!< define to 1, if the upper case value of a code is needed
16776#endif
168
16977#ifndef   NEED_UNICODE_LCASE
17078#define   NEED_UNICODE_LCASE      1      //!< define to 1, if the lower case value of a code is needed
17179#endif
172
17380#ifndef   NEED_UNICODE_TCASE
17481#define   NEED_UNICODE_TCASE      1      //!< define to 1, if the title case value of a code is needed
17582#endif
176
17783#ifndef   NEED_UNICODE_WIDTH
17884#define   NEED_UNICODE_WIDTH      1      //!< define to 1, if the glyph width of a code is needed
17985#endif
18086
87#define UTF8_CHAR_MAX         6      //!< maximum size of Unicode UTF-8 encoding
88#define UTF16_CHAR_MAX         2      //!< maximum size of Unicode UTF-16 encoding
89
90/* these are UTF-8 encoded strings for common characters */
91#define UTF8_NBSP           "\xc2\xa0"          //!< non-breaking space
92#define UTF8_MULTIPLY       "\xc3\x97"          //!< multiplication symbol
93#define UTF8_DEGREES        "\xc2\xb0"          //!< degrees symbol
94
95#define a_RING              "\xc3\xa5"          //!< small a with a ring
96#define a_UMLAUT            "\xc3\xa4"          //!< small a with an umlaut
97#define o_UMLAUT            "\xc3\xb6"          //!< small o with an umlaut
98#define u_UMLAUT            "\xc3\xbc"          //!< small u with an umlaut
99#define e_ACUTE             "\xc3\xa9"          //!< small e with an acute
100
101#define A_RING              "\xc3\x85"          //!< capital A with a ring
102#define A_UMLAUT            "\xc3\x84"          //!< capital A with an umlaut
103#define O_UMLAUT            "\xc3\x96"          //!< capital O with an umlaut
104#define U_UMLAUT            "\xc3\x9c"          //!< capital U with an umlaut
105#define E_ACUTE             "\xc3\x89"          //!< capital E with an acute
106
107#define UTF8_LEFT           "\xe2\x86\x90"      //!< cursor left
108#define UTF8_RIGHT          "\xe2\x86\x92"      //!< cursor right
109#define UTF8_UP             "\xe2\x86\x91"      //!< cursor up
110#define UTF8_DOWN           "\xe2\x86\x93"      //!< cursor down
111
112
113
114/***************************************************************************
115   TYPE DEFINITIONS
116***************************************************************************/
117
118typedef UINT16 utf16_char;                  //!< type used for UTF-16 encoded values
119typedef UINT32 unicode_char;               //!< type used for full width Unicode values
120
121
122
123/***************************************************************************
124   FUNCTION PROTOTYPES
125***************************************************************************/
126
127//! tests to see if a unicode char is a valid code point
128int uchar_isvalid(unicode_char uchar);
129
130//! convert an UTF-8 sequence into an unicode character
131int uchar_from_utf8(unicode_char *uchar, const char *utf8char, size_t count);
132
133//! convert a UTF-16 sequence into an unicode character
134int uchar_from_utf16(unicode_char *uchar, const utf16_char *utf16char, size_t count);
135
136//! convert a UTF-16 sequence into an unicode character from a flipped byte order
137int uchar_from_utf16f(unicode_char *uchar, const utf16_char *utf16char, size_t count);
138
139//! convert an unicode character into a UTF-8 sequence
140int utf8_from_uchar(char *utf8string, size_t count, unicode_char uchar);
141
142//! convert an unicode character into a UTF-16 sequence
143int utf16_from_uchar(utf16_char *utf16string, size_t count, unicode_char uchar);
144
145//! convert an unicode character into a UTF-16 sequence with flipped endianness
146int utf16f_from_uchar(utf16_char *utf16string, size_t count, unicode_char uchar);
147
148/* misc UTF-8 helpers */
149//! return a pointer to the previous character in a string
150const char *utf8_previous_char(const char *utf8string);
151
152//! return true if the given string is a properly formed sequence of UTF-8 characters
153int utf8_is_valid_string(const char *utf8string);
154
155//! return the number of decoded Unicode values in UTF-8 encoded string
156size_t utf8_strlen(const char* src);
157
158/* 8 bit code to Unicode value lookup table handling (e.g. ISO-8859-1 aka Latin1) */
159//! load a table translating UINT8 (unsigned char) to Unicode values
160unicode_char * uchar_table_load(const char* name);
161
162//! reverse lookup of uchar in a Unicode table
163UINT8 uchar_table_index(unicode_char* table, unicode_char uchar);
164
165//! free a unicode table
166void uchar_table_free(unicode_char* table);
167
168/* unicode_char array functions - string.h like */
169//! return the unicode_char array length
170size_t uchar_strlen(const unicode_char* src);
171
172//! compare two unicode_char arrays
173int uchar_strcmp(const unicode_char* dst, const unicode_char* src);
174
175//! compare two unicode_char arrays with length limiting
176int uchar_strncmp(const unicode_char* dst, const unicode_char* src, size_t len);
177
178//! print a formatted string of ASCII characters to an unicode_char array (max 256 characters)
179int uchar_sprintf(unicode_char* dst, const char* format, ...);
180
181//! copy an array of unicode_char from source to destination
182unicode_char* uchar_strcpy(unicode_char* dst, const unicode_char* src);
183
184//! copy a length limited array of unicode_char from source to destination
185unicode_char* uchar_strncpy(unicode_char* dst, const unicode_char* src, size_t len);
186
187/***************************************************************************
188 *   unicode.org published UnicodeData.txt
189 *  Parser and property accessors
190 ***************************************************************************/
191
192//! load the specified UnicodeData.txt file an parse it
193int unicode_data_load(const char* name);
194
195//! free the UnicodeData.txt table memory
196void unicode_data_free();
197
181198#if   NEED_UNICODE_GCAT
199/**
200 * @brief enumeration of the possible general categories
201 */
182202typedef enum {
183203   gcat_0,      //!< invalid value
184204   gcat_Lu,   //!< Letter, Uppercase
r26170r26171
215235#endif
216236
217237#if   NEED_UNICODE_BIDI
238/**
239 * @brief enumeration of the possible bidirectional categories
240 */
218241typedef enum {
219242   bidi_0,      //!< invalid value
220243   bidi_L,      //!< Left-to-Right
r26170r26171
240263#endif
241264
242265#if   NEED_UNICODE_DECO
266/**
267 * @brief enumeration of the possible decomposition mappings
268 */
243269typedef enum {
244270   deco_0,         //!< invalid value
245271   deco_canonical, //!< canonical mapping

Previous 199869 Revisions Next


© 1997-2024 The MAME Team