aboutsummaryrefslogtreecommitdiff
path: root/src/menu.c
blob: 2c5db536b80f23b7763a25118371f50190f36236 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include "globals.h"

void do_menu(struct player_t *player, const struct command_t *commands, uint len, const char *prompt)
{
    for(uint i = 0; i < len; ++i)
    {
        output("%d. %s\n", i + 1, commands[i].name);
    }

    output("%s", prompt);
    char *cmdbuf = read_string();

    all_lower(cmdbuf);

    /* find the best command */

    int best_command = -1;

    /* first, search for an exact match */
    for(uint i = 0; i < len; ++i)
    {
        if(strcmp(cmdbuf, commands[i].command) == 0)
        {
            best_command = i;
            goto exec_cmd;
        }
    }

    /* look for a number and see if it corresponds to a valid command */
    ulong n = strtol(cmdbuf, NULL, 10);
    if(0 < n && n <= len)
    {
        /* in range, execute */
        best_command = n - 1;
        goto exec_cmd;
    }

    /* now look for a partial match */
    for(uint i = 0; i < len; ++i)
    {
        uint len = strlen(cmdbuf);
        if(len > strlen(commands[i].command))
            continue;
        for(uint j = 1; j <= len; ++j)
        {
            char *buf1 = malloc(j + 1);
            memset(buf1, 0, j + 1);
            memcpy(buf1, cmdbuf, j);
            buf1[j] = '\0';

            char *buf2 = malloc(j + 1);
            memset(buf2, 0, j + 1);
            memcpy(buf2, commands[i].command, j);
            buf2[j] = '\0';

            if(strcmp(buf1, buf2) == 0)
            {
                best_command = i;
                free(buf1);
                free(buf2);
                goto exec_cmd;
            }
            else
            {
                free(buf1);
                free(buf2);
            }
        }
    }

exec_cmd:

    if(best_command >= 0)
    {
        if(batch_mode)
            output("\n");
        commands[best_command].handler(player);
        output("\n");
    }
    else
    {
        output("Unrecognized command: '%s'\n", cmdbuf);
    }

    free(cmdbuf);
}