+ /* Special one-character word? */
+ if (!isalnum ((unsigned char) *string))
+ {
+ *word_len = 1;
+ return string;
+ }
+
+ /* Alphanumeric word. */
+ *word_len = 1;
+ while (isalnum ((unsigned char) string[*word_len]))
+ (*word_len)++;
+
+ return string;
+}
+
+/* Returns nonzero if strings A and B can be confused based on
+ their first three letters. */
+static int
+conflicting_3char_prefixes (const char *a, const char *b)
+{
+ size_t aw_len, bw_len;
+ const char *aw, *bw;
+
+ aw = find_word (a, &aw_len);
+ bw = find_word (b, &bw_len);
+ assert (aw != NULL && bw != NULL);
+
+ return ((aw_len > 3 && bw_len > 3)
+ || (aw_len == 3 && bw_len > 3)
+ || (bw_len == 3 && aw_len > 3)) && !memcmp (aw, bw, 3);
+}
+
+/* Returns nonzero if CMD can be confused with another command
+ based on the first three letters of its first word. */
+static int
+conflicting_3char_prefix_command (const struct command *cmd)
+{
+ assert (cmd >= commands && cmd < commands + COMMAND_CNT);
+
+ return ((cmd > commands
+ && conflicting_3char_prefixes (cmd[-1].name, cmd[0].name))
+ || (cmd < commands + COMMAND_CNT
+ && conflicting_3char_prefixes (cmd[0].name, cmd[1].name)));
+}
+
+/* Ways that a set of words can match a command name. */
+enum command_match