summaryrefslogtreecommitdiff
path: root/src/core/commands.h
blob: 3201c5abd24863e0dab30d897aad3006c87606f3 (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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#ifndef __COMMANDS_H
#define __COMMANDS_H

#include "signals.h"

typedef struct {
        int count;
	char *category;
	char *cmd;
	char **options;
} COMMAND_REC;

enum {
	CMDERR_OPTION_UNKNOWN = -3, /* unknown -option */
	CMDERR_OPTION_AMBIGUOUS = -2, /* ambiguous -option */
	CMDERR_OPTION_ARG_MISSING = -1, /* argument missing for -option */

	CMDERR_UNKNOWN, /* unknown command */
	CMDERR_AMBIGUOUS, /* ambiguous command */

        CMDERR_ERRNO, /* get the error from errno */
	CMDERR_NOT_ENOUGH_PARAMS, /* not enough parameters given */
	CMDERR_NOT_CONNECTED, /* not connected to IRC server */
	CMDERR_NOT_JOINED, /* not joined to any channels in this window */
	CMDERR_CHAN_NOT_FOUND, /* channel not found */
	CMDERR_CHAN_NOT_SYNCED, /* channel not fully synchronized yet */
	CMDERR_NOT_GOOD_IDEA /* not good idea to do, -yes overrides this */
};

/* Return the full command for `alias' */
#define alias_find(alias) \
	iconfig_get_str("aliases", alias, NULL)

/* Returning from command function with error */
#define cmd_return_error(a) \
	{ signal_emit("error command", 1, GINT_TO_POINTER(a)); signal_stop(); return; }
#define cmd_param_error(a) \
	{ cmd_params_free(free_arg); cmd_return_error(a); }

extern GSList *commands;
extern char *current_command; /* the command we're right now. */

/* Bind command to specified function. */
void command_bind_to(int pos, const char *cmd, const char *category, SIGNAL_FUNC func);
#define command_bind(a, b, c) command_bind_to(1, a, b, c)
#define command_bind_first(a, b, c) command_bind_to(0, a, b, c)
#define command_bind_last(a, b, c) command_bind_to(2, a, b, c)
void command_unbind(const char *cmd, SIGNAL_FUNC func);

/* Run subcommand, `cmd' contains the base command, first word in `data'
   contains the subcommand */
void command_runsub(const char *cmd, const char *data, void *server, void *item);

COMMAND_REC *command_find(const char *cmd);
int command_have_sub(const char *command);

/* Specify options that command can accept. `options' contains list of
   options separated with space, each option can contain a special
   char in front of it:

   '-': optional argument
   '+': argument required
   '@': optional numeric argument

   for example if options = "save -file +nick", you can use
   /command -save -file [<filename>] -nick <nickname>

   You can call this command multiple times for same command, options
   will be merged. If there's any conflicts with option types, the last
   call will override the previous */
#define iscmdtype(c) \
        ((c) == '-' || (c) == '+' || (c) == '@')
void command_set_options(const char *cmd, const char *options);

/* count can have these flags: */
#define PARAM_WITHOUT_FLAGS(a) ((a) & 0x00ffffff)
/* don't check for quotes - "arg1 arg2" is NOT treated as one argument */
#define PARAM_FLAG_NOQUOTES 0x01000000
/* final argument gets all the rest of the arguments */
#define PARAM_FLAG_GETREST 0x02000000
/* command contains options - first you need to specify them with
   command_set_options() function. Example:

     -cmd requiredarg -noargcmd -cmd2 "another arg" -optnumarg rest of text

   You would call this with:

   // only once in init
   command_set_options("mycmd", "+cmd noargcmd -cmd2 @optnumarg");

   GHashTable *optlist;

   cmd_get_params(data, &free_me, 1 | PARAM_FLAG_OPTIONS |
                  PARAM_FLAG_GETREST, "mycmd", &optlist, &rest);

   The optlist hash table is filled:

   "cmd" = "requiredarg"
   "noargcmd" = ""
   "cmd2" = "another arg"
   "optnumarg" = "" - this is because "rest" isn't a numeric value
*/
#define PARAM_FLAG_OPTIONS 0x04000000
/* don't complain about unknown options */
#define PARAM_FLAG_UNKNOWN_OPTIONS 0x08000000

char *cmd_get_param(char **data);
/* get parameters from command - you should point free_me somewhere and
   cmd_params_free() it after you don't use any of the parameters anymore.

   Returns TRUE if all ok, FALSE if error occured. */
int cmd_get_params(const char *data, gpointer *free_me, int count, ...);

void cmd_params_free(void *free_me);

typedef char* (*CMD_GET_FUNC) (const char *data, int *count, va_list *args);
void cmd_get_add_func(CMD_GET_FUNC func);
void cmd_get_remove_func(CMD_GET_FUNC func);

void commands_init(void);
void commands_deinit(void);

#endif