Merge Irssi 0.8.16-rc1
[silc.git] / apps / irssi / src / core / levels.c
1 /*
2  levels.c : irssi
3
4     Copyright (C) 1999-2000 Timo Sirainen
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License along
17     with this program; if not, write to the Free Software Foundation, Inc.,
18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "module.h"
22 #include "levels.h"
23
24 static const char *levels[] = {
25         "CRAP",
26         "MSGS",
27         "PUBLICS",
28         "NOTICES",
29         "SNOTES",
30         "CTCPS",
31         "ACTIONS",
32         "JOINS",
33         "PARTS",
34         "QUITS",
35         "KICKS",
36         "MODES",
37         "TOPICS",
38         "WALLOPS",
39         "INVITES",
40         "NICKS",
41         "DCC",
42         "DCCMSGS",
43         "CLIENTNOTICES",
44         "CLIENTCRAP",
45         "CLIENTERRORS",
46         "HILIGHTS",
47
48         "NOHILIGHT",
49         NULL
50 };
51
52 int level_get(const char *level)
53 {
54         int n, len, match;
55
56         if (g_ascii_strcasecmp(level, "ALL") == 0 || strcmp(level, "*") == 0)
57                 return MSGLEVEL_ALL;
58
59         if (g_ascii_strcasecmp(level, "NEVER") == 0)
60                 return MSGLEVEL_NEVER;
61
62         len = strlen(level);
63         if (len == 0) return 0;
64
65         /* partial match allowed, as long as it's the only one that matches */
66         match = 0;
67         for (n = 0; levels[n] != NULL; n++) {
68                 if (g_ascii_strncasecmp(levels[n], level, len) == 0) {
69                         if ((int)strlen(levels[n]) == len) {
70                                 /* full match */
71                                 return 1L << n;
72                         }
73                         if (match > 0) {
74                                 /* ambiguous - abort */
75                                 return 0;
76                         }
77                         match = 1L << n;
78                 }
79         }
80
81         return match;
82 }
83
84 int level2bits(const char *level, int *errorp)
85 {
86         char *orig, *str, *ptr;
87         int ret, singlelevel, negative;
88
89         if (errorp != NULL)
90                 *errorp = FALSE;
91
92         g_return_val_if_fail(level != NULL, 0);
93
94         if (*level == '\0')
95                 return 0;
96
97         orig = str = g_strdup(level);
98
99         ret = 0;
100         for (ptr = str; ; str++) {
101                 if (*str == ' ')
102                         *str++ = '\0';
103                 else if (*str != '\0')
104                         continue;
105
106                 negative = *ptr == '-';
107                 if (*ptr == '-' || *ptr == '+') ptr++;
108
109                 singlelevel = level_get(ptr);
110                 if (singlelevel != 0) {
111                         ret = !negative ? (ret | singlelevel) :
112                                 (ret & ~singlelevel);
113                 } else if (errorp != NULL)
114                         *errorp = TRUE;
115
116                 while (*str == ' ') str++;
117                 if (*str == '\0') break;
118
119                 ptr = str;
120         }
121         g_free(orig);
122
123         return ret;
124 }
125
126 char *bits2level(int bits)
127 {
128         GString *str;
129         char *ret;
130         int n;
131
132         if (bits == 0)
133                 return g_strdup("");
134
135         if (bits == MSGLEVEL_ALL)
136                 return g_strdup("ALL");
137
138         str = g_string_new(NULL);
139         if (bits & MSGLEVEL_NEVER)
140                 g_string_append(str, "NEVER ");
141
142         for (n = 0; levels[n] != NULL; n++) {
143                 if (bits & (1L << n))
144                         g_string_append_printf(str, "%s ", levels[n]);
145         }
146         if (str->len > 0)
147                 g_string_truncate(str, str->len-1);
148
149         ret = str->str;
150         g_string_free(str, FALSE);
151
152         return ret;
153 }
154
155 int combine_level(int dest, const char *src)
156 {
157         char **list, **item, *itemname;
158         int itemlevel;
159
160         g_return_val_if_fail(src != NULL, dest);
161
162         list = g_strsplit(src, " ", -1);
163         for (item = list; *item != NULL; item++) {
164                 itemname = *item + (**item == '+' || **item == '-' ? 1 : 0);
165                 itemlevel = level_get(itemname);
166
167                 if (strcmp(itemname, "NONE") == 0)
168                         dest = 0;
169                 else if (**item == '-')
170                         dest &= ~(itemlevel);
171                 else
172                         dest |= itemlevel;
173         }
174         g_strfreev(list);
175
176         return dest;
177 }