2 * This file is licensed under the GPLv2 license
4 * Luiz Fernando N. Capitulino
5 * <lcapitulino@gmail.com>
16 enum dictionary_menu_opt
{
24 static const char dict_file_path
[] = "dict.txt";
30 /* skip_char(): skip a sequence of characters 'c' in 'file' */
31 static void skip_char(FILE *file
, int c
)
35 while ((rc
= getc(file
)) == c
)
40 /* skip_space(): skip spaces in 'file' */
41 static void skip_space(FILE *file
)
46 /* seek_line_end(): go to the end of a dict line */
47 static void seek_line_end(FILE *file
)
53 if (c
== EOF
|| c
== ':' || c
== '\n')
58 /* str_kill_nl(): kill a new-line character at end of line */
59 static void str_kill_nl(char *line
)
61 line
[strlen(line
) - 1] = '\0';
68 /* list_empty(): Return 1 if 'list' is empty, 0 otherwise */
69 static int list_empty(const struct dict_list
*list
)
71 return list
->first
== list
->last
;
74 /* word_compare(): comparison function used by insertion_sort() */
75 static int word_compare(const void *key1
, const void *key2
)
77 const char *str1
= ((const struct dict_line
*) key1
)->word
;
78 const char *str2
= ((const struct dict_line
*) key2
)->word
;
80 return memcmp(str1
, str2
, DICT_WORD_MAX
);
83 /* insertion_sort(): sort data by using insertion sort algorithm */
84 static int insertion_sort(void *data
, int size
, int esize
,
85 int (*compare
) (const void *key1
, const void *key2
))
91 key
= (char *) malloc(esize
);
95 for (j
= 1; j
< size
; j
++) {
96 memcpy(key
, &a
[j
* esize
], esize
);
99 while (i
>= 0 && compare(&a
[i
* esize
], key
) > 0) {
100 memcpy(&a
[(i
+ 1) * esize
], &a
[i
* esize
], esize
);
104 memcpy(&a
[(i
+ 1) * esize
], key
, esize
);
111 /* list_sort(): sort list */
112 static int list_sort(struct dict_list
*list
)
114 return insertion_sort(list
->dict_line
, list
->last
,
115 sizeof(struct dict_line
), word_compare
);
118 /* list_init(): Initialize 'list' */
119 static void list_init(struct dict_list
*list
)
121 list
->first
= list
->last
= 0;
124 /* list_insert(): Insert element 'line' into 'list' */
125 static int list_insert(struct dict_list
*list
, struct dict_line
*line
)
127 if (list
->last
== DICT_LIST_MAX
) {
132 list
->dict_line
[list
->last
] = *line
;
138 /* list_remove(): Removes element at position 'pos' from 'list', the
139 * elements' address is returned in 'ret' */
140 static int list_remove(int pos
,
141 struct dict_list
*list
, struct dict_line
*ret
)
145 if (list_empty(list
) || pos
>= list
->last
)
149 *ret
= list
->dict_line
[pos
];
153 for (i
= pos
; i
< list
->last
; i
++)
154 list
->dict_line
[i
] = list
->dict_line
[i
+ 1];
159 /* list_write(): Write 'list' to the dict file */
160 static int list_write(struct dict_list
*list
)
165 dict
= fopen(dict_file_path
, "w");
169 for (i
= 0; i
< list
->last
; i
++) {
170 fprintf(dict
, "%s: %s\n",
171 list
->dict_line
[i
].word
, list
->dict_line
[i
].tip
);
178 /* show_entry(): print 'entry' in a standard way */
179 static void show_entry(int nr
, const struct dict_line
*entry
)
181 printf("%d. word: %s\n", nr
, entry
->word
);
182 printf(" tip: %s\n", entry
->tip
);
186 /* list_print(): Print 'list' to the standard output */
187 static void list_print(const struct dict_list
*list
)
191 if (list_empty(list
))
196 for (i
= 0; i
< list
->last
; i
++)
197 show_entry(i
, &list
->dict_line
[i
]);
200 static void handle_pattern(char *pattern
,
201 const struct dict_list
*list
)
205 if (pattern
[0] == '\n') {
211 pattern
[strlen(pattern
) - 1] = '\0';
213 for (i
= 0; i
< list
->last
; i
++) {
214 if (strstr(list
->dict_line
[i
].word
, pattern
)) {
215 show_entry(i
, &list
->dict_line
[i
]);
221 printf("\n-> Nao encontrado\n");
224 static void show_prompt(void)
228 printf("Aperte <enter> para fazer a pesquisa e "
229 "Ctrl-D para sair\n\n");
233 static void list_search(const struct dict_list
*list
)
236 char pattern
[DICT_WORD_MAX
];
241 ret
= fgets(pattern
, sizeof(pattern
), stdin
);
245 handle_pattern(pattern
, list
);
251 * Dict high level functions
254 /* dict_read_line(): read a line from dict file 'file' and return it
255 * in 'line' of size 'size' */
256 static int dict_read_line(FILE *file
, char *line
, size_t size
)
262 memset(line
, 0, size
);
266 for (i
= 0; i
< size
; i
++) {
268 if (c
== EOF
|| c
== ':' || c
== '\n') {
284 /* dict_read_file(): read the entire dict file in the 'dict_line'
285 * array, of elements 'size'. Return the number of read elements
287 static int dict_read_file(struct dict_line
*dict_line
, size_t size
, int *read
)
295 dict
= fopen(dict_file_path
, "r");
299 for (i
= 0; i
< size
; i
++) {
300 ret
= dict_read_line(dict
, dict_line
[i
].word
, DICT_WORD_MAX
);
304 ret
= dict_read_line(dict
, dict_line
[i
].tip
, DICT_TIP_MAX
);
315 /* dict_read_user(): Read a dict line from the user */
316 static void dict_read_user(struct dict_line
*line
)
319 line
->word
[0] = line
->tip
[0] = '\0';
322 printf("Entre com a palavra chave: ");
323 fgets(line
->word
, DICT_WORD_MAX
, stdin
);
324 str_kill_nl(line
->word
);
327 printf("Entre com a dica: ");
328 fgets(line
->tip
, DICT_TIP_MAX
, stdin
);
329 str_kill_nl(line
->tip
);
336 void dict_pick_up_word(struct dict_line
*line
)
339 struct dict_list list
;
343 err
= dict_read_file(list
.dict_line
, DICT_LIST_MAX
, &list
.last
);
344 if (err
&& errno
!= ENOENT
) {
345 eprint("dict_read_file() failed");
351 *line
= list
.dict_line
[rand() % list
.last
];
354 void dictionary_menu(void)
357 struct dict_line line
;
358 struct dict_list list
;
362 err
= dict_read_file(list
.dict_line
, DICT_LIST_MAX
, &list
.last
);
363 if (err
&& errno
!= ENOENT
) {
364 eprint("dict_read_file() failed");
369 err
= list_sort(&list
);
371 eprint("insertion_sort() failed");
376 printf("\nManipular dicionario\n\n");
377 printf("1. Imprimir conteudo\n"
383 scanf("%d", (int *) &op
);
395 dict_read_user(&line
);
396 err
= list_insert(&list
, &line
);
404 printf("Digite o numero para remover: ");
407 err
= list_remove(pos
, &list
, NULL
);
417 eprint("Function not implemented");