//////////////////////////////////////////////////////////////////////////////// // Lexer::Type::tag // ^ | <isWhiteSpace> [ +|- ] <isIdentifierStart> [ <isIdentifierNext> ]* bool Lexer::isTag (std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; // Lookbehind: ^ | <isWhiteSpace> if (marker > 0 && ! isWhitespace (_text[marker - 1])) return false; if (_text[marker] == '+' || _text[marker] == '-') { ++marker; if (isIdentifierStart (_text[marker])) { utf8_next_char (_text, marker); while (isIdentifierNext (_text[marker])) utf8_next_char (_text, marker); token = _text.substr (_cursor, marker - _cursor); type = Lexer::Type::tag; _cursor = marker; return true; } } return false; }
void gui_input_delete_previous_word () { int length_deleted, size_deleted; char *start, *string; if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos > 0) { start = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos - 1); string = start; while (string && (string[0] == ' ')) { string = utf8_prev_char (gui_current_window->buffer->input_buffer, string); } if (string) { while (string && (string[0] != ' ')) { string = utf8_prev_char (gui_current_window->buffer->input_buffer, string); } if (string) { while (string && (string[0] == ' ')) { string = utf8_prev_char (gui_current_window->buffer->input_buffer, string); } } } if (string) string = utf8_next_char (utf8_next_char (string)); else string = gui_current_window->buffer->input_buffer; size_deleted = utf8_next_char (start) - string; length_deleted = utf8_strnlen (string, size_deleted); gui_input_clipboard_copy (string, size_deleted); gui_input_move (gui_current_window->buffer, string, string + size_deleted, strlen (string + size_deleted)); gui_current_window->buffer->input_buffer_size -= size_deleted; gui_current_window->buffer->input_buffer_length -= length_deleted; gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; gui_current_window->buffer->input_buffer_pos -= length_deleted; gui_input_optimize_size (gui_current_window->buffer); gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } }
//////////////////////////////////////////////////////////////////////////////// // Compares two strings with offsets, and returns the number bytes in common. // // left: wonderful // l: ^ // right: prowonderbread // r: ^ // returns: ^ 6 std::string::size_type Lexer::commonLength ( const std::string& left, std::string::size_type l, const std::string& right, std::string::size_type r) { while (left[l] == right[r] && utf8_next_char (left, l) && utf8_next_char (right, r)) ; return l; }
int gui_chat_string_real_pos (const char *string, int pos) { const char *real_pos, *ptr_string; int size_on_screen; if (pos <= 0) return 0; real_pos = string; ptr_string = string; while (ptr_string && ptr_string[0] && (pos > 0)) { ptr_string = gui_chat_string_next_char (NULL, (unsigned char *)ptr_string, 0); if (ptr_string) { size_on_screen = (((unsigned char)ptr_string[0]) < 32) ? 1 : utf8_char_size_screen (ptr_string); if (size_on_screen > 0) pos -= size_on_screen; ptr_string = utf8_next_char (ptr_string); real_pos = ptr_string; } } return 0 + (real_pos - string); }
const std::string obfuscateText (const std::string& input) { std::stringstream output; std::string::size_type i = 0; int character; bool inside = false; while ((character = utf8_next_char (input, i))) { if (inside) { output << (char) character; if (character == 'm') inside = false; } else { if (character == 033) inside = true; if (inside || character == ' ') output << (char) character; else output << 'x'; } } return output.str (); }
int gui_chat_string_real_pos (const char *string, int pos, int use_screen_size) { const char *real_pos, *real_pos_prev, *ptr_string; int size_on_screen; if (pos <= 0) return 0; real_pos = string; real_pos_prev = string; ptr_string = string; while (ptr_string && ptr_string[0] && (pos >= 0)) { ptr_string = gui_chat_string_next_char (NULL, NULL, (unsigned char *)ptr_string, 0, 0, 0); if (ptr_string) { size_on_screen = gui_chat_char_size_screen (ptr_string); if (size_on_screen > 0) pos -= (use_screen_size) ? size_on_screen : 1; ptr_string = utf8_next_char (ptr_string); real_pos_prev = real_pos; real_pos = ptr_string; } } if (pos < 0) real_pos = real_pos_prev; return 0 + (real_pos - string); }
int longestWord (const std::string& input) { int longest = 0; int length = 0; std::string::size_type i = 0; int character; while ((character = utf8_next_char (input, i))) { if (character == ' ') { if (length > longest) longest = length; length = 0; } else length += mk_wcwidth (character); } if (length > longest) longest = length; return longest; }
void gui_input_delete_next_word () { int size_deleted, length_deleted; char *start, *string; if (gui_current_window->buffer->input) { start = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos); string = start; length_deleted = 0; while (string[0]) { if ((string[0] == ' ') && (string > start)) break; string = utf8_next_char (string); length_deleted++; } size_deleted = string - start; gui_input_clipboard_copy (start, size_deleted); gui_input_move (gui_current_window->buffer, start, string, strlen (string)); gui_current_window->buffer->input_buffer_size -= size_deleted; gui_current_window->buffer->input_buffer_length -= length_deleted; gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; gui_input_optimize_size (gui_current_window->buffer); gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } }
void gui_chat_get_word_info (struct t_gui_window *window, const char *data, int *word_start_offset, int *word_end_offset, int *word_length_with_spaces, int *word_length) { const char *start_data; char *next_char, *next_char2; int leading_spaces, char_size_screen; *word_start_offset = 0; *word_end_offset = 0; *word_length_with_spaces = 0; *word_length = 0; start_data = data; leading_spaces = 1; while (data && data[0]) { next_char = gui_chat_string_next_char (window, NULL, (unsigned char *)data, 0, 0, 0); if (next_char) { next_char2 = utf8_next_char (next_char); if (next_char2) { if (next_char[0] != ' ') { if (leading_spaces) *word_start_offset = next_char - start_data; leading_spaces = 0; *word_end_offset = next_char2 - start_data - 1; char_size_screen = gui_chat_char_size_screen (next_char); (*word_length_with_spaces) += char_size_screen; (*word_length) += char_size_screen; } else { if (leading_spaces) { (*word_length_with_spaces)++; *word_end_offset = next_char2 - start_data - 1; } else { *word_end_offset = next_char - start_data - 1; return; } } data = next_char2; } } else { *word_end_offset = data + strlen (data) - start_data - 1; return; } } }
STATIC void uni_print_json(void (*print)(void *env, const char *fmt, ...), void *env, const byte *str_data, uint str_len) { print(env, "\""); const byte *s = str_data, *top = str_data + str_len; while (s < top) { unichar ch; ch = utf8_get_char(s); s = utf8_next_char(s); if (ch == '"' || ch == '\\' || ch == '/') { print(env, "\\%c", ch); } else if (32 <= ch && ch <= 126) { print(env, "%c", ch); } else if (*s == '\b') { print(env, "\\b"); } else if (*s == '\f') { print(env, "\\f"); } else if (*s == '\n') { print(env, "\\n"); } else if (*s == '\r') { print(env, "\\r"); } else if (*s == '\t') { print(env, "\\t"); } else { print(env, "\\u%04x", ch); } } print(env, "\""); }
void gui_input_move_previous_word () { char *pos; if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos > 0) { pos = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos - 1); while (pos && (pos[0] == ' ')) { pos = utf8_prev_char (gui_current_window->buffer->input_buffer, pos); } if (pos) { while (pos && (pos[0] != ' ')) { pos = utf8_prev_char (gui_current_window->buffer->input_buffer, pos); } if (pos) pos = utf8_next_char (pos); else pos = gui_current_window->buffer->input_buffer; gui_current_window->buffer->input_buffer_pos = utf8_pos (gui_current_window->buffer->input_buffer, pos - gui_current_window->buffer->input_buffer); } else gui_current_window->buffer->input_buffer_pos = 0; gui_input_text_cursor_moved_signal (); } } }
void gui_input_delete_next_char () { char *pos, *pos_next; int char_size, size_to_move; if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos < gui_current_window->buffer->input_buffer_length) { pos = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos); pos_next = utf8_next_char (pos); char_size = pos_next - pos; size_to_move = strlen (pos_next); gui_input_move (gui_current_window->buffer, pos, pos_next, size_to_move); gui_current_window->buffer->input_buffer_size -= char_size; gui_current_window->buffer->input_buffer_length--; gui_current_window->buffer->input_buffer[gui_current_window->buffer->input_buffer_size] = '\0'; gui_input_optimize_size (gui_current_window->buffer); gui_completion_stop (gui_current_window->buffer->completion, 1); gui_input_text_changed_modifier_and_signal (gui_current_window->buffer); } } }
int istalk(unsigned char* words) { unsigned char* word = words; while (*word) { if (word[0] == '?' || word[0] == '/' || word[0] == 0x27 || word[0] == '+' || word[0] == ',') // || word[0] == ';' ) // 0x27 = ' ; else if (word[0] == 0xef && word[1] == 0xbc && word[2] == 0x9f) //「?」 ; else if (word[0] != 0xe3) return 0; else if (word[1] == 0x80 && (word[2] == 0x81 || word[2] == 0x82)) // 、。 ; else if (word[1] == 0x83 && word[2] == 0xbc) // ー ; else if (word[1] == 0x81 && word[2] > 0x80) // あ~ ; else if (word[1] == 0x82 && word[2] < 0x94) // ~ん ; else return 0; word = utf8_next_char(word); } return 1; }
void replaceGrass(unsigned char* str) { unsigned char buf[BUFSIZE]; unsigned char* str_p = buf; unsigned char* next = NULL; int prev_is_w = 0; int len; strcpy(buf, str); while(*str_p) { next = utf8_next_char(str_p); len = next - str_p; if (*str_p == 'w' || str_p[0] == 0xef && str_p[1] == 0xbd && str_p[2] == 0x97) { if (prev_is_w < 2) { memcpy(str, "わら", 6); str += 6; prev_is_w++; } } else { memcpy(str, str_p, len); str += len; prev_is_w = 0; } str_p = next; } *str = '\0'; }
//////////////////////////////////////////////////////////////////////////////// // Lexer::Type::url // http [s] :// ... bool Lexer::isURL (std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; if (_eos - _cursor > 9 && // length 'https://*' (_text[marker + 0] == 'h' || _text[marker + 0] == 'H') && (_text[marker + 1] == 't' || _text[marker + 1] == 'T') && (_text[marker + 2] == 't' || _text[marker + 2] == 'T') && (_text[marker + 3] == 'p' || _text[marker + 3] == 'P')) { marker += 4; if (_text[marker + 0] == 's' || _text[marker + 0] == 'S') ++marker; if (_text[marker + 0] == ':' && _text[marker + 1] == '/' && _text[marker + 2] == '/') { marker += 3; while (marker < _eos && ! isWhitespace (_text[marker])) utf8_next_char (_text, marker); token = _text.substr (_cursor, marker - _cursor); type = Lexer::Type::url; _cursor = marker; return true; } } return false; }
int longestLine (const std::string& input) { int longest = 0; int length = 0; std::string::size_type i = 0; int character; while ((character = utf8_next_char (input, i))) { if (character == '\n') { if (length > longest) longest = length; length = 0; } else ++length; } if (length > longest) longest = length; return longest; }
int utf8_char_size (const char *string) { if (!string) return 0; return utf8_next_char (string) - string; }
int utf8_strlen(char const *p) { int i; if (!p) return 0; for (i = 0; *p; i++) { p = utf8_next_char(p); } return i; }
char *utf8_offset_to_pointer(char const *str, int offset) { if (offset < 0) { return NULL; } for(;offset--;) { str = utf8_next_char(str); } return (char *)str; }
bool Lexer::isOneWord (const std::string& text) { std::string::size_type i = 0; int character; while ((character = utf8_next_char (text, i))) if (Lexer::isWhitespace (character)) return false; return true; }
//////////////////////////////////////////////////////////////////////////////// // Lexer::Type::identifier // <isIdentifierStart> [ <isIdentifierNext> ]* bool Lexer::isIdentifier (std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; if (isIdentifierStart (_text[marker])) { utf8_next_char (_text, marker); while (isIdentifierNext (_text[marker])) utf8_next_char (_text, marker); token = _text.substr (_cursor, marker - _cursor); type = Lexer::Type::identifier; _cursor = marker; return true; } return false; }
bool nontrivial (const std::string& input) { std::string::size_type i = 0; int character; while ((character = utf8_next_char (input, i))) if (! Lexer::isWhitespace (character)) return true; return false; }
int utf8_pointer_to_offset(char const *str, char const * const pos) { int ret = 0; if (pos < str) { ret = - utf8_pointer_to_offset (pos, str); } else { for(; str < pos; ret++) { str = utf8_next_char(str); } } return ret; }
//////////////////////////////////////////////////////////////////////////////// // Lexer::Type::path // ( / <non-slash, non-whitespace> )+ bool Lexer::isPath (std::string& token, Lexer::Type& type) { std::size_t marker = _cursor; int slashCount = 0; while (1) { if (_text[marker] == '/') { ++marker; ++slashCount; } else break; if (_text[marker] && ! isWhitespace (_text[marker]) && _text[marker] != '/') { utf8_next_char (_text, marker); while (_text[marker] && ! isWhitespace (_text[marker]) && _text[marker] != '/') utf8_next_char (_text, marker); } else break; } if (marker > _cursor && slashCount > 3) { type = Lexer::Type::path; token = _text.substr (_cursor, marker - _cursor); _cursor = marker; return true; } return false; }
char * utf8_add_offset (const char *string, int offset) { if (!string) return NULL; while (string && string[0] && (offset > 0)) { string = utf8_next_char (string); offset--; } return (char *)string; }
TEST(Utf8, Move) { char *ptr; /* previous/next char */ POINTERS_EQUAL(NULL, utf8_prev_char (NULL, NULL)); POINTERS_EQUAL(NULL, utf8_next_char (NULL)); ptr = utf8_next_char (noel_valid); STRCMP_EQUAL("oël", ptr); ptr = utf8_next_char (ptr); STRCMP_EQUAL("ël", ptr); ptr = utf8_next_char (ptr); STRCMP_EQUAL("l", ptr); ptr = utf8_prev_char (noel_valid, ptr); ptr = utf8_prev_char (noel_valid, ptr); ptr = utf8_prev_char (noel_valid, ptr); STRCMP_EQUAL("noël", ptr); POINTERS_EQUAL(noel_valid, ptr); /* add offset */ ptr = utf8_add_offset (noel_valid, 0); STRCMP_EQUAL(noel_valid, ptr); ptr = utf8_add_offset (noel_valid, 1); STRCMP_EQUAL("oël", ptr); ptr = utf8_add_offset (noel_valid, 3); STRCMP_EQUAL("l", ptr); /* real position */ LONGS_EQUAL(0, utf8_real_pos (noel_valid, 0)); LONGS_EQUAL(1, utf8_real_pos (noel_valid, 1)); LONGS_EQUAL(2, utf8_real_pos (noel_valid, 2)); LONGS_EQUAL(4, utf8_real_pos (noel_valid, 3)); /* position */ LONGS_EQUAL(0, utf8_pos (noel_valid, 0)); LONGS_EQUAL(1, utf8_pos (noel_valid, 1)); LONGS_EQUAL(2, utf8_pos (noel_valid, 2)); LONGS_EQUAL(3, utf8_pos (noel_valid, 4)); }
void gui_input_move_next_word () { char *pos; if (gui_current_window->buffer->input) { if (gui_current_window->buffer->input_buffer_pos < gui_current_window->buffer->input_buffer_length) { pos = utf8_add_offset (gui_current_window->buffer->input_buffer, gui_current_window->buffer->input_buffer_pos); while (pos[0] && (pos[0] == ' ')) { pos = utf8_next_char (pos); } if (pos[0]) { while (pos[0] && (pos[0] != ' ')) { pos = utf8_next_char (pos); } if (pos[0]) gui_current_window->buffer->input_buffer_pos = utf8_pos (gui_current_window->buffer->input_buffer, pos - gui_current_window->buffer->input_buffer); else gui_current_window->buffer->input_buffer_pos = gui_current_window->buffer->input_buffer_length; } else gui_current_window->buffer->input_buffer_pos = utf8_pos (gui_current_window->buffer->input_buffer, utf8_prev_char (gui_current_window->buffer->input_buffer, pos) - gui_current_window->buffer->input_buffer); gui_input_text_cursor_moved_signal (); } } }
static void text_model_keysym(void *data, struct text_model *text_model, uint32_t serial, uint32_t time, uint32_t key, uint32_t state, uint32_t modifiers) { struct text_entry *entry = data; const char *state_label = "release"; const char *key_label = "Unknown"; const char *new_char; if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { state_label = "pressed"; } if (key == XKB_KEY_Left || key == XKB_KEY_Right) { if (state != WL_KEYBOARD_KEY_STATE_RELEASED) return; if (key == XKB_KEY_Left) new_char = utf8_prev_char(entry->text, entry->text + entry->cursor); else new_char = utf8_next_char(entry->text + entry->cursor); if (new_char != NULL) { entry->cursor = new_char - entry->text; if (!(modifiers & entry->keysym.shift_mask)) entry->anchor = entry->cursor; widget_schedule_redraw(entry->widget); } return; } switch (key) { case XKB_KEY_Tab: key_label = "Tab"; break; case XKB_KEY_KP_Enter: case XKB_KEY_Return: key_label = "Enter"; break; } fprintf(stderr, "%s key was %s.\n", key_label, state_label); }
int util_version_number (const char *version) { char **items, buf[64], *error; const char *ptr_item; int num_items, i, version_int[4], index_buf; long number; items = string_split (version, ".", 0, 4, &num_items); for (i = 0; i < 4; i++) { version_int[i] = 0; if (items && (i < num_items)) { ptr_item = items[i]; index_buf = 0; while (ptr_item && ptr_item[0] && (index_buf < (int)sizeof (buf) - 1)) { if (ptr_item[0] == '-') break; if (isdigit ((unsigned char)ptr_item[0])) { buf[index_buf] = ptr_item[0]; index_buf++; } ptr_item = utf8_next_char (ptr_item); } buf[index_buf] = '\0'; if (buf[0]) { error = NULL; number = strtol (buf, &error, 10); if (error && !error[0]) { if (number < 0) number = 0; else if (number > 0xFF) number = 0xFF; version_int[i] = number; } } } } if (items) string_free_split (items); return (version_int[0] << 24) | (version_int[1] << 16) | (version_int[2] << 8) | version_int[3]; }
const char * gui_chat_string_add_offset (const char *string, int offset) { while (string && string[0] && (offset > 0)) { string = gui_chat_string_next_char (NULL, NULL, (unsigned char *)string, 0, 0, 0); if (string) { string = utf8_next_char (string); offset--; } } return string; }