/** Test funckji dictionary_hints(). Wstawienie do słownika 7 słów. Sprawdzenie, czy funkcja zwraca prawidłowe podpowiedzi. */ static void dictionary_hints_test(void** state) { struct dictionary *dict; dict = dictionary_new(); struct word_list *l = malloc(sizeof(word_list)); word_list_init(l); wchar_t *word1 = L"at"; wchar_t *word2 = L"car"; wchar_t *word3 = L"cat"; wchar_t *word4 = L"cats"; wchar_t *word5 = L"cut"; wchar_t *word6 = L"mat"; wchar_t *word7 = L"rat"; dictionary_insert(dict, word1); dictionary_insert(dict, word2); dictionary_insert(dict, word3); dictionary_insert(dict, word4); dictionary_insert(dict, word5); dictionary_insert(dict, word6); dictionary_insert(dict, word7); dictionary_hints(dict, word3, l); assert_string_equal(l->next->word, word1); assert_string_equal(l->next->next->word, word2); assert_string_equal(l->next->next->next->word, word3); assert_string_equal(l->next->next->next->next->word, word4); assert_string_equal(l->next->next->next->next->next->word, word5); assert_string_equal(l->next->next->next->next->next->next->word, word6); assert_string_equal(l->next->next->next->next->next->next->next->word, word7); word_list_done(l); dictionary_done(dict); free(l); }
/** Przetwarza jedno słowo @param[in,out] index Indeks znaku w buforze @param[in,out] char_number Nr znaku w aktualnie przetwarzanej linii @param[in,out] line_number Nr linii przetwarzanej @param[in] buffer Bufor @param[in] dict Słownik @param[in] v_option Czy włączono opcję -v */ void parse_word(int *index, int *char_number, int *line_number, wchar_t *buffer, struct dictionary *dict, bool v_option) { const int first_char = *char_number; vector *word = vector_new(sizeof(wchar_t), BUFFER_START_SIZE); for(; iswalpha(buffer[*index]); (*index)++, (*char_number)++) vector_push_back(word, buffer + *index); vector_push_back(word, L"\0"); (*index)--; (*char_number)--; wchar_t *word_content = vector_content(word); wchar_t *word_small = malloc(vector_size(word) * sizeof(wchar_t)); for(int i = 0; i < vector_size(word); i++) word_small[i] = towlower(word_content[i]); if(!dictionary_find(dict, word_small)) { wprintf(L"#"); if(v_option) { fwprintf(stderr, L"%d,%d %ls:", *line_number, first_char, word_content); struct word_list list; dictionary_hints(dict, word_small, &list); const wchar_t * const *hints = word_list_get(&list); int number_of_hints = word_list_size(&list); for(int i = 0; i < number_of_hints; i++) fwprintf(stderr, L" %ls", hints[i]); if(number_of_hints == 0) fwprintf(stderr, L" "); fwprintf(stderr, L"\n"); } } wprintf(L"%ls", word_content); free(word_small); vector_done(word); }
/** * Funkcja, która finalizuje wczytywanie słowa i wypisuje o nim informacje. * Na standardowe wyjście słowo zostaje przepisane, lub przepisane poprzedzone * znakiem '#', jeśli go nie znaleziono w słowniku. * Jeśli w 'pstate' ustawiony jest tryb "verbose", wypisywane są również * dodatkowe informacje o podpowiedziach na wyjście błędów. * @param [in,out] pstate Stan parsera. Zostanie uaktualniona jedynie pozycja * w buforze. */ void process_word(struct parser_state * pstate) { // finalizing buffer iterator *pstate->buffer_iterator = L'\0'; pstate->buffer_iterator = word_buffer; // word for dictionary make_lower(word_buffer, word_buffer_lowered); // true position of the word int word_column_num = pstate->last_non_word_column_num + 1; // getting data from dictionary and printing it const bool is_in_dict = dictionary_find(pstate->dict, word_buffer_lowered); if (!is_in_dict && pstate->verbose) { { struct word_list wlist; dictionary_hints(pstate->dict, word_buffer_lowered, &wlist); print_verbose_info(pstate, word_column_num, &wlist, stderr); } fputwc(L'#', stdout); } fputws(word_buffer, stdout); }
/// Testuje listę podpowiedzi do różnych słów static void dict_hints_test(void **state) { struct dictionary* d = *state; struct word_list* l = malloc(sizeof(struct word_list)); dictionary_hints(d, L"aab", l); assert_int_equal(word_list_size(l), 3); const wchar_t* const* array = word_list_get(l); assert_int_equal(wcscmp(array[0], L"aa"), 0); assert_int_equal(wcscmp(array[1], L"ab"), 0); assert_int_equal(wcscmp(array[2], L"cab"), 0); word_list_done(l); dictionary_hints(d, L"aa", l); assert_int_equal(word_list_size(l), 2); array = word_list_get(l); assert_int_equal(wcscmp(array[0], L"aa"), 0); assert_int_equal(wcscmp(array[1], L"ab"), 0); word_list_done(l); dictionary_hints(d, L"ab", l); assert_int_equal(word_list_size(l), 4); array = word_list_get(l); assert_int_equal(wcscmp(array[0], L"aa"), 0); assert_int_equal(wcscmp(array[1], L"ab"), 0); assert_int_equal(wcscmp(array[2], L"b"), 0); assert_int_equal(wcscmp(array[3], L"cab"), 0); word_list_done(l); dictionary_hints(d, L"ca", l); assert_int_equal(word_list_size(l), 3); array = word_list_get(l); assert_int_equal(wcscmp(array[0], L"aa"), 0); assert_int_equal(wcscmp(array[1], L"c"), 0); assert_int_equal(wcscmp(array[2], L"cab"), 0); word_list_done(l); dictionary_hints(d, L"a", l); assert_int_equal(word_list_size(l), 4); array = word_list_get(l); assert_int_equal(wcscmp(array[0], L"aa"), 0); assert_int_equal(wcscmp(array[1], L"ab"), 0); assert_int_equal(wcscmp(array[2], L"b"), 0); assert_int_equal(wcscmp(array[3], L"c"), 0); word_list_done(l); free(l); }
/** Sprawdzenie słowa, na którym aktualnie znajduje się kursor. Ewentualne dodanie do słownika. @param[in] item element menu. @param[in] data wskaźnik na wartość. */ static void WhatCheck (GtkMenuItem *item, gpointer data) { GtkWidget *dialog; GtkTextIter start, end; char *word; gunichar *wword; //load_dictionary_from_menu(&dict); // Znajdujemy pozycję kursora gtk_text_buffer_get_iter_at_mark(editor_buf, &start, gtk_text_buffer_get_insert(editor_buf)); // Jeśli nie wewnątrz słowa, kończymy if (!gtk_text_iter_inside_word(&start)) { dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Kursor musi być w środku słowa"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } // Znajdujemy początek i koniec słowa, a potem samo słowo end = start; gtk_text_iter_backward_word_start(&start); gtk_text_iter_forward_word_end(&end); word = gtk_text_iter_get_text(&start, &end); // Zamieniamy na wide char (no prawie) wword = g_utf8_to_ucs4_fast(word, -1, NULL); if (!make_lowercase(wword)) { dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Podane słowo nie jest słowem słownikowym."); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { // Sprawdzamy if (dictionary_find(dict, (wchar_t *)wword)) { dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Wszystko w porządku,\nśpij spokojnie"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { // Czas korekty GtkWidget *vbox, *label, *combo; struct word_list hints; int i; wchar_t **words; dictionary_hints(dict, (wchar_t *)wword, &hints); words = (wchar_t **) word_list_get(&hints); dialog = gtk_dialog_new_with_buttons("Korekta", NULL, 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_ADD, GTK_RESPONSE_APPLY, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); // W treści dialogu dwa elementy vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); // Tekst label = gtk_label_new("Słowo nie znajduje się w słowniku. Wybierz \njedną z propozycji lub dodaj słowa do słownika."); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 1); // Spuszczane menu combo = gtk_combo_box_text_new(); for (i = 0; i < word_list_size(&hints); i++) { // Combo box lubi mieć Gtk char *uword = g_ucs4_to_utf8((gunichar *)words[i], -1, NULL, NULL, NULL); // Dodajemy kolejny element gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), uword); g_free(uword); } gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 1); gtk_widget_show(combo); gint click = gtk_dialog_run(GTK_DIALOG(dialog)); if (click == GTK_RESPONSE_ACCEPT) { char *korekta = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo)); // Usuwamy stare gtk_text_buffer_delete(editor_buf, &start, &end); // Wstawiamy nowe gtk_text_buffer_insert(editor_buf, &start, korekta, -1); g_free(korekta); } // Proponujemy dodanie słowa do słownika else if (click == GTK_RESPONSE_APPLY) dictionary_insert(dict, wword); gtk_widget_destroy(dialog); } } g_free(word); g_free(wword); }
static void WhatCheck (GtkMenuItem *item, gpointer data) { GtkWidget *dialog; GtkTextIter start, end; char *word; gunichar *wword; // Znajdujemy pozycję kursora gtk_text_buffer_get_iter_at_mark(editor_buf, &start, gtk_text_buffer_get_insert(editor_buf)); // Jeśli nie wewnątrz słowa, kończymy if (!gtk_text_iter_inside_word(&start)) { dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Kursor musi być w środku słowa"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } // Znajdujemy początek i koniec słowa, a potem samo słowo end = start; gtk_text_iter_backward_word_start(&start); gtk_text_iter_forward_word_end(&end); word = gtk_text_iter_get_text(&start, &end); // Zamieniamy na wide char (no prawie) wword = g_utf8_to_ucs4_fast(word, -1, NULL); if(update_actual_dict() < 0) return; // Sprawdzamy if (dictionary_find(dict, (wchar_t *)wword)) { dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Wszystko w porządku,\nśpij spokojnie"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { // Czas korekty GtkWidget *vbox, *label, *combo; struct word_list hints; int i; wchar_t **words; dictionary_hints(dict, (wchar_t *)wword, &hints); words = word_list_get(&hints); dialog = gtk_dialog_new_with_buttons("Korekta", NULL, 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); // W treści dialogu dwa elementy vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); // Tekst label = gtk_label_new("Coś nie tak, mam kilka propozycji"); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 1); // Spuszczane menu combo = gtk_combo_box_text_new(); for (i = 0; i < word_list_size(&hints); i++) { // Combo box lubi mieć Gtk char *uword = g_ucs4_to_utf8((gunichar *)words[i], -1, NULL, NULL, NULL); // Dodajemy kolejny element gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), uword); g_free(uword); } //gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo),"<inne...>"); gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 1); gtk_widget_show(combo); char *korekta, *question; GtkWidget *ask_dialog, *ask_vbox, *ask_label; switch (gtk_dialog_run(GTK_DIALOG(dialog))) { case GTK_RESPONSE_ACCEPT: korekta = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo)); // Usuwamy stare gtk_text_buffer_delete(editor_buf, &start, &end); // Wstawiamy nowe gtk_text_buffer_insert(editor_buf, &start, korekta, -1); g_free(korekta); break; case GTK_RESPONSE_REJECT: question = "Czy chcesz dodać to słowo do słownika?"; ask_dialog = gtk_dialog_new_with_buttons(question, NULL, 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); ask_vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); // Tekst ask_label = gtk_label_new("Coś nie tak, mam kilka propozycji"); gtk_widget_show(ask_label); gtk_box_pack_start(GTK_BOX(ask_vbox), ask_label, FALSE, FALSE, 1); // Jeśli chiciał dodać nowe słowo do słownika to dodamy i zapiszemy if (gtk_dialog_run(GTK_DIALOG(ask_dialog)) == GTK_RESPONSE_ACCEPT) { dictionary_insert(dict, (wchar_t *)wword); dictionary_save_lang(dict, dict_location); } gtk_widget_destroy(ask_dialog); break; } gtk_widget_destroy(dialog); } }