1 #include <stdlib.h>
2 #include <string.h>
3 #include <errno.h>
4 #include <mba/suba.h>
5 #include <mba/diff.h>
6 #include <mba/msgno.h>
7 
8 /* usage:
9  * $ ./spell skoke
10  * poke
11  * spoke
12  * spoken
13  *
14  * In practice you really need scoring so adding -ing or switching ei with
15  * ie costs less than two otherwise unrelated characters.
16  */
17 
18 #define DIFF_LIMIT 4
19 
20 char *words[] = {
21 	"poke",
22 	"poker",
23 	"pokeweed",
24 	"recessed",
25 	"recession",
26 	"recessional",
27 	"recessionary",
28 	"recessive",
29 	"recharge",
30 	"rechargeable",
31 	"rechauffe",
32 	"recidivism",
33 	"recidivist",
34 	"Recife",
35 	"recipe",
36 	"recipient",
37 	"reciprocal",
38 	"reciprocality",
39 	"reciprocate",
40 	"reciprocating",
41 	"reciprocation",
42 	"reciprocative",
43 	"reciprocity",
44 	"recission",
45 	"recital",
46 	"recitalist",
47 	"recitation",
48 	"recitative",
49 	"recite",
50 	"reciter",
51 	"recklessly",
52 	"recklessness",
53 	"reckon",
54 	"reckoner",
55 	"reckoning",
56 	"reclaim",
57 	"reclaimable",
58 	"reclamation",
59 	"reclassification",
60 	"reclassify",
61 	"recline",
62 	"recliner",
63 	"reclining",
64 	"recluse",
65 	"split",
66 	"splitter",
67 	"splotch",
68 	"splurge",
69 	"splutter",
70 	"spluttering",
71 	"Spock",
72 	"Spode",
73 	"Spodoptera",
74 	"spodumene",
75 	"spoil",
76 	"spoilage",
77 	"spoiled",
78 	"spoiler",
79 	"spoilsport",
80 	"Spokane",
81 	"spoke",
82 	"spoken",
83 	"spokesman",
84 	"spokesperson",
85 	"spokeswoman",
86 	NULL
87 };
88 int
lookup(const char * word)89 lookup(const char *word)
90 {
91 	unsigned char mem[4096];
92 	struct allocator *al = suba_init(mem, 4096, 1, 0);
93 	struct varray buf;
94 	int m[1024], max, i, wlen = strlen(word), d;
95 
96 	varray_init(&buf, sizeof(int), al);
97 
98 	for (i = 0; words[i]; i++) {
99 		m[i] = strlen(words[i]);
100 	}
101 	max = i;
102 
103 	for (i = 0; i < max; i++) {
104 		if ((d = diff(word, 0, wlen, words[i], 0, m[i],
105 					NULL, NULL, NULL, DIFF_LIMIT, NULL, NULL, &buf)) == -1) {
106 			MMNO(errno);
107 			return EXIT_FAILURE;
108 		}
109 		if (d == 0) {
110 			printf("exact match\n");
111 			return 0;
112 		} else if (d < DIFF_LIMIT) {
113 			printf("%s\n", words[i]);
114 		}
115 	}
116 
117 	return 0;
118 }
119 
120 int
main(int argc,char * argv[])121 main(int argc, char *argv[])
122 {
123 	if (argc < 2) {
124 		fprintf(stderr, "usage: spell <word>\n");
125 		return EXIT_FAILURE;
126 	}
127 
128 	if (lookup(argv[1]) == -1) {
129 		MMSG("");
130 		return EXIT_FAILURE;
131 	}
132 
133 	return EXIT_SUCCESS;
134 }
135 
136