
to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
173 lines
4.1 KiB
C
173 lines
4.1 KiB
C
//===-- dictionary.c ---------------------------------------------*- C -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===---------------------------------------------------------------------===//
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
typedef struct tree_node {
|
|
const char *word;
|
|
struct tree_node *left;
|
|
struct tree_node *right;
|
|
} tree_node;
|
|
|
|
/* Given a char*, returns a substring that starts at the first
|
|
alphabet character and ends at the last alphabet character, i.e. it
|
|
strips off beginning or ending quotes, punctuation, etc. */
|
|
|
|
char *strip(char **word) {
|
|
char *start = *word;
|
|
int len = strlen(start);
|
|
char *end = start + len - 1;
|
|
|
|
while ((start < end) && (!isalpha(start[0])))
|
|
start++;
|
|
|
|
while ((end > start) && (!isalpha(end[0])))
|
|
end--;
|
|
|
|
if (start > end)
|
|
return NULL;
|
|
|
|
end[1] = '\0';
|
|
*word = start;
|
|
|
|
return start;
|
|
}
|
|
|
|
/* Given a binary search tree (sorted alphabetically by the word at
|
|
each node), and a new word, inserts the word at the appropriate
|
|
place in the tree. */
|
|
|
|
void insert(tree_node *root, char *word) {
|
|
if (root == NULL)
|
|
return;
|
|
|
|
int compare_value = strcmp(word, root->word);
|
|
|
|
if (compare_value == 0)
|
|
return;
|
|
|
|
if (compare_value < 0) {
|
|
if (root->left != NULL)
|
|
insert(root->left, word);
|
|
else {
|
|
tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
|
|
new_node->word = strdup(word);
|
|
new_node->left = NULL;
|
|
new_node->right = NULL;
|
|
root->left = new_node;
|
|
}
|
|
} else {
|
|
if (root->right != NULL)
|
|
insert(root->right, word);
|
|
else {
|
|
tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
|
|
new_node->word = strdup(word);
|
|
new_node->left = NULL;
|
|
new_node->right = NULL;
|
|
root->right = new_node;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Read in a text file and storea all the words from the file in a
|
|
binary search tree. */
|
|
|
|
void populate_dictionary(tree_node **dictionary, char *filename) {
|
|
FILE *in_file;
|
|
char word[1024];
|
|
|
|
in_file = fopen(filename, "r");
|
|
if (in_file) {
|
|
while (fscanf(in_file, "%s", word) == 1) {
|
|
char *new_word = (strdup(word));
|
|
new_word = strip(&new_word);
|
|
if (*dictionary == NULL) {
|
|
tree_node *new_node = (tree_node *)malloc(sizeof(tree_node));
|
|
new_node->word = new_word;
|
|
new_node->left = NULL;
|
|
new_node->right = NULL;
|
|
*dictionary = new_node;
|
|
} else
|
|
insert(*dictionary, new_word);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Given a binary search tree and a word, search for the word
|
|
in the binary search tree. */
|
|
|
|
int find_word(tree_node *dictionary, char *word) {
|
|
if (!word || !dictionary)
|
|
return 0;
|
|
|
|
int compare_value = strcmp(word, dictionary->word);
|
|
|
|
if (compare_value == 0)
|
|
return 1;
|
|
else if (compare_value < 0)
|
|
return find_word(dictionary->left, word);
|
|
else
|
|
return find_word(dictionary->right, word);
|
|
}
|
|
|
|
/* Print out the words in the binary search tree, in sorted order. */
|
|
|
|
void print_tree(tree_node *dictionary) {
|
|
if (!dictionary)
|
|
return;
|
|
|
|
if (dictionary->left)
|
|
print_tree(dictionary->left);
|
|
|
|
printf("%s\n", dictionary->word);
|
|
|
|
if (dictionary->right)
|
|
print_tree(dictionary->right);
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
tree_node *dictionary = NULL;
|
|
char buffer[1024];
|
|
char *filename;
|
|
int done = 0;
|
|
|
|
if (argc == 2)
|
|
filename = argv[1];
|
|
|
|
if (!filename)
|
|
return -1;
|
|
|
|
populate_dictionary(&dictionary, filename);
|
|
fprintf(stdout, "Dictionary loaded.\nEnter search word: ");
|
|
while (!done && fgets(buffer, sizeof(buffer), stdin)) {
|
|
char *word = buffer;
|
|
int len = strlen(word);
|
|
int i;
|
|
|
|
for (i = 0; i < len; ++i)
|
|
word[i] = tolower(word[i]);
|
|
|
|
if ((len > 0) && (word[len - 1] == '\n')) {
|
|
word[len - 1] = '\0';
|
|
len = len - 1;
|
|
}
|
|
|
|
if (find_word(dictionary, word))
|
|
fprintf(stdout, "Yes!\n");
|
|
else
|
|
fprintf(stdout, "No!\n");
|
|
|
|
fprintf(stdout, "Enter search word: ");
|
|
}
|
|
|
|
fprintf(stdout, "\n");
|
|
return 0;
|
|
}
|