Added SILC Thread Queue API
[crypto.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
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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_strcasecmp(level, "ALL") == 0 || strcmp(level, "*") == 0)
57                 return MSGLEVEL_ALL;
58
59         if (g_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_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)
85 {
86         char *orig, *str, *ptr;
87         int ret, singlelevel, negative;
88
89         g_return_val_if_fail(level != NULL, 0);
90
91         if (*level == '\0')
92                 return 0;
93
94         orig = str = g_strdup(level);
95
96         ret = 0;
97         for (ptr = str; ; str++) {
98                 if (*str == ' ')
99                         *str++ = '\0';
100                 else if (*str != '\0')
101                         continue;
102
103                 negative = *ptr == '-';
104                 if (*ptr == '-' || *ptr == '+') ptr++;
105
106                 singlelevel = level_get(ptr);
107                 if (singlelevel != 0) {
108                         ret = !negative ? (ret | singlelevel) :
109                                 (ret & ~singlelevel);
110                 }
111
112                 while (*str == ' ') str++;
113                 if (*str == '\0') break;
114
115                 ptr = str;
116         }
117         g_free(orig);
118
119         return ret;
120 }
121
122 char *bits2level(int bits)
123 {
124         GString *str;
125         char *ret;
126         int n;
127
128         if (bits == 0)
129                 return g_strdup("");
130
131         if (bits == MSGLEVEL_ALL)
132                 return g_strdup("ALL");
133
134         str = g_string_new(NULL);
135         if (bits & MSGLEVEL_NEVER)
136                 g_string_append(str, "NEVER ");
137
138         for (n = 0; levels[n] != NULL; n++) {
139                 if (bits & (1L << n))
140                         g_string_sprintfa(str, "%s ", levels[n]);
141         }
142         if (str->len > 0)
143                 g_string_truncate(str, str->len-1);
144
145         ret = str->str;
146         g_string_free(str, FALSE);
147
148         return ret;
149 }
150
151 int combine_level(int dest, const char *src)
152 {
153         char **list, **item, *itemname;
154         int itemlevel;
155
156         g_return_val_if_fail(src != NULL, dest);
157
158         list = g_strsplit(src, " ", -1);
159         for (item = list; *item != NULL; item++) {
160                 itemname = *item + (**item == '+' || **item == '-' ? 1 : 0);
161                 g_strup(itemname);
162                 itemlevel = level_get(itemname);
163
164                 if (strcmp(itemname, "NONE") == 0)
165                         dest = 0;
166                 else if (**item == '-')
167                         dest &= ~(itemlevel);
168                 else
169                         dest |= itemlevel;
170         }
171         g_strfreev(list);
172
173         return dest;
174 }