xref: /openbsd-src/gnu/llvm/lldb/examples/scripting/dictionary.c (revision 061da546b983eb767bad15e67af1174fb0bcf31c)
1*061da546Spatrick //===-- dictionary.c ---------------------------------------------*- C -*-===//
2*061da546Spatrick //
3*061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5*061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*061da546Spatrick //
7*061da546Spatrick //===---------------------------------------------------------------------===//
8*061da546Spatrick #include <ctype.h>
9*061da546Spatrick #include <stdio.h>
10*061da546Spatrick #include <stdlib.h>
11*061da546Spatrick #include <string.h>
12*061da546Spatrick 
13*061da546Spatrick typedef struct tree_node {
14*061da546Spatrick   const char *word;
15*061da546Spatrick   struct tree_node *left;
16*061da546Spatrick   struct tree_node *right;
17*061da546Spatrick } tree_node;
18*061da546Spatrick 
19*061da546Spatrick /* Given a char*, returns a substring that starts at the first
20*061da546Spatrick    alphabet character and ends at the last alphabet character, i.e. it
21*061da546Spatrick    strips off beginning or ending quotes, punctuation, etc. */
22*061da546Spatrick 
strip(char ** word)23*061da546Spatrick char *strip(char **word) {
24*061da546Spatrick   char *start = *word;
25*061da546Spatrick   int len = strlen(start);
26*061da546Spatrick   char *end = start + len - 1;
27*061da546Spatrick 
28*061da546Spatrick   while ((start < end) && (!isalpha(start[0])))
29*061da546Spatrick     start++;
30*061da546Spatrick 
31*061da546Spatrick   while ((end > start) && (!isalpha(end[0])))
32*061da546Spatrick     end--;
33*061da546Spatrick 
34*061da546Spatrick   if (start > end)
35*061da546Spatrick     return NULL;
36*061da546Spatrick 
37*061da546Spatrick   end[1] = '\0';
38*061da546Spatrick   *word = start;
39*061da546Spatrick 
40*061da546Spatrick   return start;
41*061da546Spatrick }
42*061da546Spatrick 
43*061da546Spatrick /* Given a binary search tree (sorted alphabetically by the word at
44*061da546Spatrick    each node), and a new word, inserts the word at the appropriate
45*061da546Spatrick    place in the tree.  */
46*061da546Spatrick 
insert(tree_node * root,char * word)47*061da546Spatrick void insert(tree_node *root, char *word) {
48*061da546Spatrick   if (root == NULL)
49*061da546Spatrick     return;
50*061da546Spatrick 
51*061da546Spatrick   int compare_value = strcmp(word, root->word);
52*061da546Spatrick 
53*061da546Spatrick   if (compare_value == 0)
54*061da546Spatrick     return;
55*061da546Spatrick 
56*061da546Spatrick   if (compare_value < 0) {
57*061da546Spatrick     if (root->left != NULL)
58*061da546Spatrick       insert(root->left, word);
59*061da546Spatrick     else {
60*061da546Spatrick       tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
61*061da546Spatrick       new_node->word = strdup(word);
62*061da546Spatrick       new_node->left = NULL;
63*061da546Spatrick       new_node->right = NULL;
64*061da546Spatrick       root->left = new_node;
65*061da546Spatrick     }
66*061da546Spatrick   } else {
67*061da546Spatrick     if (root->right != NULL)
68*061da546Spatrick       insert(root->right, word);
69*061da546Spatrick     else {
70*061da546Spatrick       tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
71*061da546Spatrick       new_node->word = strdup(word);
72*061da546Spatrick       new_node->left = NULL;
73*061da546Spatrick       new_node->right = NULL;
74*061da546Spatrick       root->right = new_node;
75*061da546Spatrick     }
76*061da546Spatrick   }
77*061da546Spatrick }
78*061da546Spatrick 
79*061da546Spatrick /* Read in a text file and storea all the words from the file in a
80*061da546Spatrick    binary search tree.  */
81*061da546Spatrick 
populate_dictionary(tree_node ** dictionary,char * filename)82*061da546Spatrick void populate_dictionary(tree_node **dictionary, char *filename) {
83*061da546Spatrick   FILE *in_file;
84*061da546Spatrick   char word[1024];
85*061da546Spatrick 
86*061da546Spatrick   in_file = fopen(filename, "r");
87*061da546Spatrick   if (in_file) {
88*061da546Spatrick     while (fscanf(in_file, "%s", word) == 1) {
89*061da546Spatrick       char *new_word = (strdup(word));
90*061da546Spatrick       new_word = strip(&new_word);
91*061da546Spatrick       if (*dictionary == NULL) {
92*061da546Spatrick         tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
93*061da546Spatrick         new_node->word = new_word;
94*061da546Spatrick         new_node->left = NULL;
95*061da546Spatrick         new_node->right = NULL;
96*061da546Spatrick         *dictionary = new_node;
97*061da546Spatrick       } else
98*061da546Spatrick         insert(*dictionary, new_word);
99*061da546Spatrick     }
100*061da546Spatrick   }
101*061da546Spatrick }
102*061da546Spatrick 
103*061da546Spatrick /* Given a binary search tree and a word, search for the word
104*061da546Spatrick    in the binary search tree.  */
105*061da546Spatrick 
find_word(tree_node * dictionary,char * word)106*061da546Spatrick int find_word(tree_node *dictionary, char *word) {
107*061da546Spatrick   if (!word || !dictionary)
108*061da546Spatrick     return 0;
109*061da546Spatrick 
110*061da546Spatrick   int compare_value = strcmp(word, dictionary->word);
111*061da546Spatrick 
112*061da546Spatrick   if (compare_value == 0)
113*061da546Spatrick     return 1;
114*061da546Spatrick   else if (compare_value < 0)
115*061da546Spatrick     return find_word(dictionary->left, word);
116*061da546Spatrick   else
117*061da546Spatrick     return find_word(dictionary->right, word);
118*061da546Spatrick }
119*061da546Spatrick 
120*061da546Spatrick /* Print out the words in the binary search tree, in sorted order.  */
121*061da546Spatrick 
print_tree(tree_node * dictionary)122*061da546Spatrick void print_tree(tree_node *dictionary) {
123*061da546Spatrick   if (!dictionary)
124*061da546Spatrick     return;
125*061da546Spatrick 
126*061da546Spatrick   if (dictionary->left)
127*061da546Spatrick     print_tree(dictionary->left);
128*061da546Spatrick 
129*061da546Spatrick   printf("%s\n", dictionary->word);
130*061da546Spatrick 
131*061da546Spatrick   if (dictionary->right)
132*061da546Spatrick     print_tree(dictionary->right);
133*061da546Spatrick }
134*061da546Spatrick 
main(int argc,char ** argv)135*061da546Spatrick int main(int argc, char **argv) {
136*061da546Spatrick   tree_node *dictionary = NULL;
137*061da546Spatrick   char buffer[1024];
138*061da546Spatrick   char *filename;
139*061da546Spatrick   int done = 0;
140*061da546Spatrick 
141*061da546Spatrick   if (argc == 2)
142*061da546Spatrick     filename = argv[1];
143*061da546Spatrick 
144*061da546Spatrick   if (!filename)
145*061da546Spatrick     return -1;
146*061da546Spatrick 
147*061da546Spatrick   populate_dictionary(&dictionary, filename);
148*061da546Spatrick   fprintf(stdout, "Dictionary loaded.\nEnter search word: ");
149*061da546Spatrick   while (!done && fgets(buffer, sizeof(buffer), stdin)) {
150*061da546Spatrick     char *word = buffer;
151*061da546Spatrick     int len = strlen(word);
152*061da546Spatrick     int i;
153*061da546Spatrick 
154*061da546Spatrick     for (i = 0; i < len; ++i)
155*061da546Spatrick       word[i] = tolower(word[i]);
156*061da546Spatrick 
157*061da546Spatrick     if ((len > 0) && (word[len - 1] == '\n')) {
158*061da546Spatrick       word[len - 1] = '\0';
159*061da546Spatrick       len = len - 1;
160*061da546Spatrick     }
161*061da546Spatrick 
162*061da546Spatrick     if (find_word(dictionary, word))
163*061da546Spatrick       fprintf(stdout, "Yes!\n");
164*061da546Spatrick     else
165*061da546Spatrick       fprintf(stdout, "No!\n");
166*061da546Spatrick 
167*061da546Spatrick     fprintf(stdout, "Enter search word: ");
168*061da546Spatrick   }
169*061da546Spatrick 
170*061da546Spatrick   fprintf(stdout, "\n");
171*061da546Spatrick   return 0;
172*061da546Spatrick }
173