branches/alto2/src/emu/debug/dvbpoints.c
| r26376 | r26377 | |
| 345 | 345 | |
| 346 | 346 | // Draw |
| 347 | 347 | debug_view_char *dest = m_viewdata; |
| 348 | size_t width = 256; |
| 349 | unicode_char buffer[256+1]; |
| 348 | 350 | for (int row = 0; row < m_visible.y; row++) |
| 349 | 351 | { |
| 350 | 352 | UINT32 effrow = m_topleft.y + row; |
| 353 | for (size_t i = 0; i < width; i++) |
| 354 | buffer[i] = ' '; |
| 351 | 355 | |
| 352 | 356 | // Header |
| 353 | 357 | if (row == 0) |
| 354 | 358 | { |
| 355 | | astring header; |
| 356 | | header.printf("ID"); |
| 357 | | if (m_sortType == SORT_INDEX_ASCENDING) header.catprintf("\\"); |
| 358 | | else if (m_sortType == SORT_INDEX_DESCENDING) header.catprintf("/"); |
| 359 | | pad_astring_to_length(header, tableBreaks[0]); |
| 360 | | header.catprintf("En"); |
| 361 | | if (m_sortType == SORT_ENABLED_ASCENDING) header.catprintf("\\"); |
| 362 | | else if (m_sortType == SORT_ENABLED_DESCENDING) header.catprintf("/"); |
| 363 | | pad_astring_to_length(header, tableBreaks[1]); |
| 364 | | header.catprintf("CPU"); |
| 365 | | if (m_sortType == SORT_CPU_ASCENDING) header.catprintf("\\"); |
| 366 | | else if (m_sortType == SORT_CPU_DESCENDING) header.catprintf("/"); |
| 367 | | pad_astring_to_length(header, tableBreaks[2]); |
| 368 | | header.catprintf("Address"); |
| 369 | | if (m_sortType == SORT_ADDRESS_ASCENDING) header.catprintf("\\"); |
| 370 | | else if (m_sortType == SORT_ADDRESS_DESCENDING) header.catprintf("/"); |
| 371 | | pad_astring_to_length(header, tableBreaks[3]); |
| 372 | | header.catprintf("Condition"); |
| 373 | | if (m_sortType == SORT_CONDITION_ASCENDING) header.catprintf("\\"); |
| 374 | | else if (m_sortType == SORT_CONDITION_DESCENDING) header.catprintf("/"); |
| 375 | | pad_astring_to_length(header, tableBreaks[4]); |
| 376 | | header.catprintf("Action"); |
| 377 | | if (m_sortType == SORT_ACTION_ASCENDING) header.catprintf("\\"); |
| 378 | | else if (m_sortType == SORT_ACTION_DESCENDING) header.catprintf("/"); |
| 379 | | pad_astring_to_length(header, tableBreaks[5]); |
| 359 | const unicode_char up_arrow = 0x25b2; // BLACK UP-POINTING TRIANGLE "▲" |
| 360 | const unicode_char down_arrow = 0x25bc; // BLACK DOWN-POINTING TRIANGLE "▼" |
| 361 | int col = uchar_snprintf(buffer, width, "ID"); |
| 362 | if (m_sortType == SORT_INDEX_ASCENDING) buffer[col++] = down_arrow; |
| 363 | else if (m_sortType == SORT_INDEX_DESCENDING) buffer[col++] = up_arrow; |
| 364 | col = tableBreaks[0]; |
| 365 | col += uchar_snprintf(&buffer[col], width - col, "En"); |
| 366 | if (m_sortType == SORT_ENABLED_ASCENDING) buffer[col] = down_arrow; |
| 367 | else if (m_sortType == SORT_ENABLED_DESCENDING) buffer[col] = up_arrow; |
| 368 | col = tableBreaks[1]; |
| 369 | col += uchar_snprintf(&buffer[col], width - col, "CPU"); |
| 370 | if (m_sortType == SORT_CPU_ASCENDING) buffer[col] = down_arrow; |
| 371 | else if (m_sortType == SORT_CPU_DESCENDING) buffer[col] = up_arrow; |
| 372 | col = tableBreaks[2]; |
| 373 | col += uchar_snprintf(&buffer[col], width - col, "Address"); |
| 374 | if (m_sortType == SORT_ADDRESS_ASCENDING) buffer[col] = down_arrow; |
| 375 | else if (m_sortType == SORT_ADDRESS_DESCENDING) buffer[col] = up_arrow; |
| 376 | col = tableBreaks[3]; |
| 377 | col += uchar_snprintf(&buffer[col], width - col, "Condition"); |
| 378 | if (m_sortType == SORT_CONDITION_ASCENDING) buffer[col] = down_arrow; |
| 379 | else if (m_sortType == SORT_CONDITION_DESCENDING) buffer[col] = up_arrow; |
| 380 | col = tableBreaks[4]; |
| 381 | col += uchar_snprintf(&buffer[col], width - col, "Action"); |
| 382 | if (m_sortType == SORT_ACTION_ASCENDING) buffer[col] = down_arrow; |
| 383 | else if (m_sortType == SORT_ACTION_DESCENDING) buffer[col] = up_arrow; |
| 380 | 384 | |
| 381 | | for (int i = 0; i < m_visible.x; i++) |
| 382 | | { |
| 383 | | dest->uchar = (i < header.len()) ? header[i] : ' '; |
| 385 | for (size_t i = 0; i < m_visible.x && i < width; i++) { |
| 386 | dest->uchar = buffer[i]; |
| 384 | 387 | dest->attrib = DCA_ANCILLARY; |
| 385 | 388 | dest++; |
| 386 | 389 | } |
| r26376 | r26377 | |
| 391 | 394 | int bpi = effrow-1; |
| 392 | 395 | if (bpi < numBPs && bpi >= 0) |
| 393 | 396 | { |
| 397 | const unicode_char checked = 0x25a3; // WHITE SQUARE CONTAINING BLACK SMALL SQUARE "▣" |
| 398 | const unicode_char unchecked = 0x25a1; // WHITE SQUARE "□" |
| 394 | 399 | device_debug::breakpoint* bp = bpList[bpi]; |
| 395 | | |
| 396 | | astring buffer; |
| 397 | | buffer.printf("%x", bp->index()); |
| 398 | | pad_astring_to_length(buffer, tableBreaks[0]); |
| 399 | | buffer.catprintf("%c", bp->enabled() ? 'X' : 'O'); |
| 400 | | pad_astring_to_length(buffer, tableBreaks[1]); |
| 401 | | buffer.catprintf("%s", bp->debugInterface()->device().tag()); |
| 402 | | pad_astring_to_length(buffer, tableBreaks[2]); |
| 403 | | buffer.catprintf("%s", core_i64_hex_format(bp->address(), bp->debugInterface()->logaddrchars())); |
| 404 | | pad_astring_to_length(buffer, tableBreaks[3]); |
| 400 | uchar_snprintf(buffer, width, "%x", bp->index()); |
| 401 | int col = tableBreaks[0]; |
| 402 | buffer[col] = bp->enabled() ? checked : unchecked; |
| 403 | col = tableBreaks[1]; |
| 404 | uchar_snprintf(&buffer[col], width - col, "%s", bp->debugInterface()->device().tag()); |
| 405 | col = tableBreaks[2]; |
| 406 | uchar_snprintf(&buffer[col], width - col, "%s", core_i64_hex_format(bp->address(), bp->debugInterface()->logaddrchars())); |
| 407 | col = tableBreaks[3]; |
| 405 | 408 | if (astring(bp->condition()) != astring("1")) |
| 406 | | { |
| 407 | | buffer.catprintf("%s", bp->condition()); |
| 408 | | pad_astring_to_length(buffer, tableBreaks[4]); |
| 409 | | } |
| 409 | uchar_snprintf(&buffer[col], width - col, "%s", bp->condition()); |
| 410 | col = tableBreaks[4]; |
| 410 | 411 | if (astring(bp->action()) != astring("")) |
| 411 | | { |
| 412 | | buffer.catprintf("%s", bp->action()); |
| 413 | | pad_astring_to_length(buffer, tableBreaks[5]); |
| 414 | | } |
| 412 | uchar_snprintf(&buffer[col], width - col, "%s", bp->action()); |
| 415 | 413 | |
| 416 | | for (int i = 0; i < m_visible.x; i++) |
| 417 | | { |
| 418 | | dest->uchar = (i < buffer.len()) ? buffer[i] : ' '; |
| 414 | for (size_t i = 0; i < m_visible.x && i < width; i++) { |
| 415 | dest->uchar = buffer[i]; |
| 419 | 416 | dest->attrib = DCA_NORMAL; |
| 420 | | |
| 421 | 417 | // Color disabled breakpoints red |
| 422 | | if (i == 5 && dest->uchar == 'O') |
| 418 | if (i == tableBreaks[0] && !bp->enabled()) |
| 423 | 419 | dest->attrib = DCA_CHANGED; |
| 424 | | |
| 425 | 420 | dest++; |
| 426 | 421 | } |
| 427 | 422 | continue; |
branches/alto2/src/emu/debug/debugvw.h
| r26376 | r26377 | |
| 46 | 46 | |
| 47 | 47 | |
| 48 | 48 | // attribute bits for debug_view_char.attrib |
| 49 | | const UINT8 DCA_NORMAL = 0x00; //!< black on white |
| 50 | | const UINT8 DCA_CHANGED = 0x01; //!< red foreground |
| 51 | | const UINT8 DCA_SELECTED = 0x02; //!< light red background |
| 52 | | const UINT8 DCA_INVALID = 0x04; //!< dark blue foreground |
| 53 | | const UINT8 DCA_DISABLED = 0x08; //!< darker foreground |
| 54 | | const UINT8 DCA_ANCILLARY = 0x10; //!< grey background |
| 55 | | const UINT8 DCA_CURRENT = 0x20; //!< yellow background |
| 56 | | const UINT8 DCA_COMMENT = 0x40; //!< green foreground |
| 57 | | const UINT8 DCA_VISITED = 0x80; //!< light blue background |
| 49 | const UINT32 DCA_NORMAL = 0; //!< black on white |
| 50 | const UINT32 DCA_CHANGED = (1 << 0); //!< red foreground |
| 51 | const UINT32 DCA_SELECTED = (1 << 1); //!< light red background |
| 52 | const UINT32 DCA_INVALID = (1 << 2); //!< dark blue foreground |
| 53 | const UINT32 DCA_DISABLED = (1 << 3); //!< darker foreground |
| 54 | const UINT32 DCA_ANCILLARY = (1 << 4); //!< grey background |
| 55 | const UINT32 DCA_CURRENT = (1 << 5); //!< yellow background |
| 56 | const UINT32 DCA_COMMENT = (1 << 6); //!< green foreground |
| 57 | const UINT32 DCA_VISITED = (1 << 7); //!< light blue background |
| 58 | const UINT32 DCA_WIDTH_MASK = (3 << 30); //!< width of the glyph in cells |
| 58 | 59 | |
| 59 | 60 | |
| 60 | 61 | // special characters that can be passed to process_char() |
| r26376 | r26377 | |
| 90 | 91 | typedef void (*debug_view_osd_update_func)(debug_view &view, void *osdprivate); |
| 91 | 92 | |
| 92 | 93 | |
| 93 | | //! a single "character" in the debug view has an Unicode value and an attribute byte |
| 94 | //! a single "character" in the debug view has an Unicode value and an attribute flags |
| 94 | 95 | struct debug_view_char |
| 95 | 96 | { |
| 96 | 97 | unicode_char uchar; |
| 97 | | UINT8 attrib; |
| 98 | UINT32 attrib; |
| 98 | 99 | }; |
| 99 | 100 | |
| 100 | 101 | |
branches/alto2/src/emu/debug/dvstate.c
| r26376 | r26377 | |
| 160 | 160 | for (state_item *item = m_state_list; item != NULL; item = item->m_next) |
| 161 | 161 | { |
| 162 | 162 | count++; |
| 163 | | maxtaglen = MAX(maxtaglen, item->m_symbol.len()); |
| 163 | maxtaglen = MAX(maxtaglen, item->m_symbol_w); |
| 164 | 164 | maxvallen = MAX(maxvallen, item->m_vallen); |
| 165 | 165 | } |
| 166 | 166 | |
| r26376 | r26377 | |
| 221 | 221 | if (curitem != NULL) |
| 222 | 222 | { |
| 223 | 223 | UINT32 effcol = m_topleft.x; |
| 224 | | UINT8 attrib = DCA_NORMAL; |
| 224 | UINT32 attrib = DCA_NORMAL; |
| 225 | 225 | UINT32 len = 0; |
| 226 | 226 | astring valstr; |
| 227 | 227 | |
| r26376 | r26377 | |
| 236 | 236 | curitem->m_symbol.reset(); |
| 237 | 237 | for (int i = 0; i < m_total.x; i++) |
| 238 | 238 | curitem->m_symbol.cat("-"); |
| 239 | curitem->m_symbol_w = utf8_width(curitem->m_symbol.cstr()); |
| 239 | 240 | break; |
| 240 | 241 | |
| 241 | 242 | case REG_CYCLES: |
| r26376 | r26377 | |
| 283 | 284 | if (curitem->m_lastval != curitem->m_currval) |
| 284 | 285 | attrib = DCA_CHANGED; |
| 285 | 286 | |
| 286 | | // build up a string |
| 287 | | char temp[256]; |
| 288 | | if (curitem->m_symbol.len() < m_divider - 1) |
| 289 | | { |
| 290 | | memset(&temp[len], ' ', m_divider - 1 - curitem->m_symbol.len()); |
| 291 | | len += m_divider - 1 - curitem->m_symbol.len(); |
| 292 | | } |
| 293 | | |
| 294 | | memcpy(&temp[len], curitem->m_symbol.cstr(), curitem->m_symbol.len()); |
| 295 | | len += curitem->m_symbol.len(); |
| 296 | | |
| 297 | | temp[len++] = ' '; |
| 298 | | temp[len++] = ' '; |
| 299 | | |
| 300 | | memcpy(&temp[len], valstr.cstr(), curitem->m_vallen); |
| 301 | | len += curitem->m_vallen; |
| 302 | | |
| 303 | | temp[len++] = ' '; |
| 287 | // build up a unciode_char string |
| 288 | unicode_char temp[256]; |
| 289 | for (int i = 0; i < ARRAY_LENGTH(temp); i++) |
| 290 | temp[i] = ' '; |
| 291 | len = curitem->m_symbol_w > m_divider - 1 ? 0 : m_divider - 1 - curitem->m_symbol_w; |
| 292 | // decode symbol UTF-8 to unicode values |
| 293 | len += ustring_from_utf8(&temp[len], ARRAY_LENGTH(temp) - len, curitem->m_symbol.cstr()); |
| 294 | len += 2; |
| 295 | // decode value UTF-8 to unicode values |
| 296 | len += ustring_from_utf8(&temp[len], ARRAY_LENGTH(temp) - len, valstr.cstr()); |
| 297 | len += 1; |
| 304 | 298 | temp[len] = 0; |
| 305 | 299 | |
| 306 | 300 | // copy data |
| r26376 | r26377 | |
| 341 | 335 | m_currval(0), |
| 342 | 336 | m_index(index), |
| 343 | 337 | m_vallen(valuechars), |
| 344 | | m_symbol(name) |
| 338 | m_symbol(name), |
| 339 | m_symbol_w(utf8_width(name)) |
| 345 | 340 | { |
| 346 | 341 | } |
branches/alto2/src/emu/debug/textbuf.c
| r26376 | r26377 | |
| 81 | 81 | text_buffer_alloc - allocate a new text buffer |
| 82 | 82 | -------------------------------------------------*/ |
| 83 | 83 | |
| 84 | | text_buffer *text_buffer_alloc(UINT32 bytes, UINT32 lines) |
| 84 | text_buffer *text_buffer_alloc(UINT32 columns, UINT32 lines) |
| 85 | 85 | { |
| 86 | 86 | text_buffer *text; |
| 87 | 87 | |
| r26376 | r26377 | |
| 91 | 91 | return NULL; |
| 92 | 92 | |
| 93 | 93 | /* allocate memory for the buffer itself */ |
| 94 | | text->buffer = (unicode_char *)osd_malloc_array(sizeof(unicode_char) * bytes); |
| 94 | text->buffer = (unicode_char *)osd_malloc_array(sizeof(unicode_char) * columns); |
| 95 | 95 | if (!text->buffer) |
| 96 | 96 | { |
| 97 | 97 | osd_free(text); |
| r26376 | r26377 | |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | 110 | /* initialize the buffer description */ |
| 111 | | text->bufsize = bytes; |
| 111 | text->bufsize = columns; |
| 112 | 112 | text->linesize = lines; |
| 113 | 113 | text_buffer_clear(text); |
| 114 | 114 | |
| r26376 | r26377 | |
| 183 | 183 | INT32 needed_space; |
| 184 | 184 | |
| 185 | 185 | /* we need to ensure there is enough space for this string plus enough for the max line length */ |
| 186 | | needed_space = utf8_ucharlen(data) + MAX_LINE_LENGTH; |
| 186 | needed_space = utf8_width(data) + MAX_LINE_LENGTH; |
| 187 | 187 | |
| 188 | 188 | /* make space in the buffer if we need to */ |
| 189 | 189 | while (buffer_space(text) < needed_space && text->linestart != text->lineend) |
| r26376 | r26377 | |
| 194 | 194 | text->bufstart = text->lineoffs[text->linestart]; |
| 195 | 195 | } |
| 196 | 196 | |
| 197 | size_t avail = strlen(data); |
| 197 | 198 | /* now add the data */ |
| 198 | 199 | while (*data) |
| 199 | 200 | { |
| 200 | | unicode_char ch; |
| 201 | unicode_char uchar; |
| 201 | 202 | int linelen; |
| 202 | | int utf8len = uchar_from_utf8(&ch, data, strlen(data)); |
| 203 | | if (utf8len > 0) |
| 204 | | data += utf8len; |
| 203 | int utf8len = uchar_from_utf8(&uchar, data, avail); |
| 204 | if (utf8len < 0) |
| 205 | break; |
| 206 | data += utf8len; |
| 207 | avail -= utf8len; |
| 205 | 208 | |
| 206 | 209 | /* a CR resets our position */ |
| 207 | | if (ch == '\r') |
| 210 | if (uchar == '\r') |
| 208 | 211 | text->bufend = text->lineoffs[text->lineend]; |
| 209 | 212 | |
| 210 | 213 | /* non-CR data is just characters */ |
| 211 | | else if (ch != '\n') |
| 212 | | text->buffer[text->bufend++] = ch; |
| 214 | else if (uchar != '\n') |
| 215 | text->buffer[text->bufend++] = uchar; |
| 213 | 216 | |
| 214 | 217 | /* an explicit newline or line-too-long condition inserts a newline */ |
| 215 | 218 | linelen = text->bufend - text->lineoffs[text->lineend]; |
| 216 | | if (ch == '\n' || linelen >= stopcol) |
| 219 | if (uchar == '\n' || linelen >= stopcol) |
| 217 | 220 | { |
| 218 | 221 | int overflow = 0; |
| 219 | 222 | |
branches/alto2/src/lib/util/unicode.c
| r26376 | r26377 | |
| 21 | 21 | */ |
| 22 | 22 | int uchar_isvalid(unicode_char uchar) |
| 23 | 23 | { |
| 24 | | return (uchar < 0x110000) && !((uchar >= 0xd800) && (uchar <= 0xdfff)); |
| 24 | return (uchar < 0x110000) && !((uchar >= 0xd800) && (uchar <= 0xdfff)); |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | 27 | |
| r26376 | r26377 | |
| 324 | 324 | * @param plen optional pointer to a size_t variable to receive the source string length |
| 325 | 325 | * @return number of unicode_char values decoded from the UTF-8 string |
| 326 | 326 | */ |
| 327 | | size_t utf8_ucharlen(const char* utf8src, size_t * plen) |
| 327 | size_t utf8_width(const char* utf8src, size_t * plen) |
| 328 | 328 | { |
| 329 | 329 | size_t len = 0; |
| 330 | 330 | size_t total = 0; |
| r26376 | r26377 | |
| 393 | 393 | * @param plen optional pointer to a size_t variable to receive the source string length |
| 394 | 394 | * @return number of unicode_char values decoded from the UTF-8 string |
| 395 | 395 | */ |
| 396 | | size_t utf16_ucharlen(const utf16_char* utf16src, size_t * plen) |
| 396 | size_t utf16_width(const utf16_char* utf16src, size_t * plen) |
| 397 | 397 | { |
| 398 | 398 | size_t len = 0; |
| 399 | 399 | size_t total = 0; |
| r26376 | r26377 | |
| 534 | 534 | } |
| 535 | 535 | |
| 536 | 536 | /** |
| 537 | | * @brief return an unicode_char array allocated while converted from UTF-8 |
| 537 | * @brief fill an unicode_char array with values decoded from UTF-8 |
| 538 | * @param ustr destination unicode_char string |
| 539 | * @param size maximum size ucharstr array in unicode_char |
| 538 | 540 | * @param utf8char source string encoded in UTF-8 |
| 539 | | * @return newly allocated unicode_char string |
| 541 | * @return number of unicode_char decoded excluding the final 0, or -1 on error |
| 540 | 542 | */ |
| 541 | | unicode_char* uchar_strfrom_utf8(const char *utf8src) |
| 543 | size_t ustring_from_utf8(unicode_char* ustr, size_t size, const char *utf8src) |
| 542 | 544 | { |
| 543 | | size_t available; |
| 544 | | size_t size = utf8_ucharlen(utf8src, &available); |
| 545 | | if (-1 == size) |
| 546 | | return NULL; |
| 547 | | unicode_char* result = (unicode_char *)calloc(sizeof(unicode_char), size + 1); |
| 548 | | unicode_char* dst = result; |
| 549 | | while (*utf8src) { |
| 550 | | unicode_char uchar = 0; |
| 551 | | int len = uchar_from_utf8(&uchar, utf8src, available); |
| 545 | size_t avail; |
| 546 | size_t width = utf8_width(utf8src, &avail); |
| 547 | if (-1 == width) |
| 548 | return width; |
| 549 | size_t length; |
| 550 | for (length = 0; *utf8src && length < size - 1; length++) |
| 551 | { |
| 552 | int len = uchar_from_utf8(&ustr[length], utf8src, avail); |
| 553 | if (len < 0) |
| 554 | break; |
| 552 | 555 | utf8src += len; |
| 553 | | available -= len; |
| 554 | | *dst++ = uchar; |
| 556 | avail -= len; |
| 555 | 557 | } |
| 556 | | return result; |
| 558 | ustr[length] = 0; |
| 559 | return length; |
| 557 | 560 | } |
| 558 | 561 | |
| 559 | 562 | /** |
| 560 | 563 | * @brief return an unicode_char array allocated while converted from UTF-16 |
| 561 | | * @param utf16src source string encoded in UTF-16 |
| 562 | | * @return newly allocated unicode_char string |
| 564 | * @param ustr destination unicode_char string |
| 565 | * @param size maximum size ucharstr array in unicode_char |
| 566 | * @param utf16char source string encoded in UTF-16 |
| 567 | * @return number of unicode_char decoded excluding the final 0, or -1 on error |
| 563 | 568 | */ |
| 564 | | unicode_char* uchar_strfrom_utf16(const utf16_char *utf16src) |
| 569 | size_t ustring_from_utf16(unicode_char* ustr, size_t size, const utf16_char *utf16src) |
| 565 | 570 | { |
| 566 | | size_t available; |
| 567 | | size_t size = utf16_ucharlen(utf16src, &available); |
| 568 | | if (-1 == size) |
| 569 | | return NULL; |
| 570 | | unicode_char* result = (unicode_char *)calloc(sizeof(unicode_char), size + 1); |
| 571 | | unicode_char* dst = result; |
| 572 | | while (*utf16src) { |
| 573 | | unicode_char uchar = 0; |
| 574 | | int len = uchar_from_utf16(&uchar, utf16src, available); |
| 571 | size_t avail; |
| 572 | size_t width = utf16_width(utf16src, &avail); |
| 573 | if (-1 == width) |
| 574 | return width; |
| 575 | size_t length; |
| 576 | for (length = 0; *utf16src && length < size - 1; length++) |
| 577 | { |
| 578 | int len = uchar_from_utf16(&ustr[length], utf16src, avail); |
| 579 | if (len < 0) |
| 580 | break; |
| 575 | 581 | utf16src += len; |
| 576 | | available -= len; |
| 577 | | *dst++ = uchar; |
| 582 | avail -= len; |
| 578 | 583 | } |
| 579 | | return result; |
| 584 | ustr[length] = 0; |
| 585 | return length; |
| 580 | 586 | } |
| 581 | 587 | |
| 582 | 588 | /** |
| r26376 | r26377 | |
| 636 | 642 | * @param format format string followed by optional parameters |
| 637 | 643 | * @return number of unicode_char stored in dst |
| 638 | 644 | */ |
| 639 | | int uchar_sprintf(unicode_char* dst, const char* format, ...) |
| 645 | int uchar_sprintf(unicode_char* ustr, const char* format, ...) |
| 640 | 646 | { |
| 641 | 647 | va_list ap; |
| 642 | 648 | char buff[256]; |
| r26376 | r26377 | |
| 644 | 650 | int len = vsnprintf(buff, sizeof(buff), format, ap); |
| 645 | 651 | va_end(ap); |
| 646 | 652 | for (int i = 0; i < len; i++) |
| 647 | | *dst++ = buff[i]; |
| 648 | | *dst = 0; |
| 653 | *ustr++ = buff[i]; |
| 654 | *ustr = 0; |
| 649 | 655 | return len; |
| 650 | 656 | } |
| 651 | 657 | |
| 652 | 658 | /** |
| 659 | * @brief print a formatted string of ASCII characters to an unicode_char array |
| 660 | * @param dst pointer to the array |
| 661 | * @param format format string followed by optional parameters |
| 662 | * @param size maximum number of unicode_char to write to dst |
| 663 | * @return number of unicode_char stored in dst |
| 664 | */ |
| 665 | int uchar_snprintf(unicode_char* ustr, size_t size, const char* format, ...) |
| 666 | { |
| 667 | va_list ap; |
| 668 | char buff[256]; |
| 669 | va_start(ap, format); |
| 670 | int len = vsnprintf(buff, sizeof(buff), format, ap); |
| 671 | va_end(ap); |
| 672 | if (len < 0) |
| 673 | return len; |
| 674 | for (int i = 0; i < len; i++) |
| 675 | *ustr++ = buff[i]; |
| 676 | *ustr = 0; |
| 677 | return len; |
| 678 | } |
| 679 | |
| 680 | /** |
| 653 | 681 | * @brief copy an array of unicode_char from source to destination |
| 654 | 682 | * |
| 655 | 683 | * @param dst pointer to destination array |
branches/alto2/src/lib/util/unicode.h
| r26376 | r26377 | |
| 145 | 145 | //! convert an unicode character into a UTF-16 sequence with flipped endianness |
| 146 | 146 | int utf16f_from_uchar(utf16_char *utf16string, size_t count, unicode_char uchar); |
| 147 | 147 | |
| 148 | | //! return the number of decoded Unicode values in UTF-8 encoded string |
| 149 | | size_t utf8_ucharlen(const char* utf8src, size_t * plen = 0); |
| 148 | //! return the width of an UTF-8 encoded string (number of decoded Unicode glyphs) |
| 149 | size_t utf8_width(const char* utf8src, size_t * plen = 0); |
| 150 | 150 | |
| 151 | | //! return the number of decoded Unicode values in UTF-16 encoded string |
| 152 | | size_t utf16_ucharlen(const utf16_char* utf16src, size_t * plen = 0); |
| 151 | //! return the width of an UTF-16 encoded string (number of decoded Unicode glyphs) |
| 152 | size_t utf16_width(const utf16_char* utf16src, size_t * plen = 0); |
| 153 | 153 | |
| 154 | 154 | /* misc UTF-8 helpers */ |
| 155 | 155 | //! return a pointer to the previous character in a string |
| r26376 | r26377 | |
| 168 | 168 | //! free a unicode table |
| 169 | 169 | void uchar_table_free(unicode_char* table); |
| 170 | 170 | |
| 171 | | //! return an unicode_char array allocated while converted from UTF-8 |
| 172 | | unicode_char* ustring_from_utf8(const char *utf8char); |
| 171 | //! fill an unicode_char array with values decoded from UTF-8 |
| 172 | size_t ustring_from_utf8(unicode_char* ucharstr, size_t max, const char *utf8char); |
| 173 | 173 | |
| 174 | | //! return an unicode_char array allocated while converted from UTF-16 |
| 175 | | unicode_char* ustring_from_utf16(const utf16_char *utf16char); |
| 174 | //! fill an unicode_char array with values decoded from UTF-16 |
| 175 | size_t ustring_from_utf16(unicode_char* ucharstr, size_t max, const utf16_char *utf16char); |
| 176 | 176 | |
| 177 | 177 | /* unicode_char array functions - string.h like */ |
| 178 | 178 | //! return the unicode_char array length |
| r26376 | r26377 | |
| 185 | 185 | int uchar_strncmp(const unicode_char* dst, const unicode_char* src, size_t len); |
| 186 | 186 | |
| 187 | 187 | //! print a formatted string of ASCII characters to an unicode_char array (max 256 characters) |
| 188 | | int uchar_sprintf(unicode_char* dst, const char* format, ...); |
| 188 | int uchar_sprintf(unicode_char* ustr, const char* format, ...); |
| 189 | 189 | |
| 190 | 190 | //! print a formatted string of ASCII characters to an unicode_char array (max size characters) |
| 191 | | int uchar_snprintf(unicode_char* dst, size_t size, const char* format, ...); |
| 191 | int uchar_snprintf(unicode_char* ustr, size_t size, const char* format, ...); |
| 192 | 192 | |
| 193 | 193 | //! copy an array of unicode_char from source to destination |
| 194 | 194 | unicode_char* uchar_strcpy(unicode_char* dst, const unicode_char* src); |