]> jfr.im git - irc/quakenet/newserv.git/blob - lib/flags.c
flags: Support more than 16 different flags.
[irc/quakenet/newserv.git] / lib / flags.c
1 /* flags.c */
2
3 #include "flags.h"
4
5 /*
6 * setflags:
7 * Applies a "+x-y+zab" style string to the inflags value.
8 *
9 * The "flagmask" input restricts the flags that can be changed.
10 * The "reject" input specifies whether to silently drop or actively reject if:
11 * REJECT_UNKNOWN: An unknown flag was specified
12 * REJECT_DISALLOWED: An attempt was made to manipute a flag disallowed by flagmask
13 */
14
15 int setflags(flag_t *inflags, flag_t flagmask, char *flagstr, const flag *flagslist, short reject) {
16 int dir,i;
17 flag_t newflags;
18 char *ch;
19
20 /* Work with a temporary copy */
21 newflags=*inflags;
22
23 /* Default is to add flags */
24 dir=1;
25
26 for(ch=flagstr;*ch;ch++) {
27 if (*ch=='+') {
28 dir=1;
29 continue;
30 }
31
32 if (*ch=='-') {
33 dir=0;
34 continue;
35 }
36
37 for(i=0;flagslist[i].flagchar!='\0';i++) {
38 if (*ch==flagslist[i].flagchar) {
39 /* Check that the change is allowed */
40 if (flagmask & flagslist[i].flagbit) {
41 if (dir==0) {
42 newflags &= (~flagslist[i].flagbit);
43 } else {
44 newflags |= flagslist[i].flagbit;
45 }
46 } else {
47 if (reject & REJECT_DISALLOWED) {
48 return REJECT_DISALLOWED;
49 }
50 }
51 /* We matched, stop looking */
52 break;
53 }
54 }
55
56 if (flagslist[i].flagchar=='\0') {
57 /* We didn't match anything */
58 if (reject & REJECT_UNKNOWN) {
59 return REJECT_UNKNOWN;
60 }
61 }
62 }
63
64 /* We reached the end without bailing out; assign the flag changes */
65 *inflags=newflags;
66 return REJECT_NONE;
67 }
68
69 /*
70 * printflags:
71 * Prints out which flags are currently set in a flag block
72 */
73 char *printflags(flag_t inflags, const flag *flaglist) {
74 static char buf[34];
75 int i;
76 char *ch=buf;
77
78 *ch++='+';
79
80 for (i=0;flaglist[i].flagchar!='\0' && i<32;i++) {
81 if (inflags&flaglist[i].flagbit) {
82 *ch++=flaglist[i].flagchar;
83 }
84 }
85
86 *ch='\0';
87 return buf;
88 }
89
90 /*
91 * printflagsornone:
92 * Prints out which flags are currently set in a flag block, or return "none"
93 */
94 char *printflagsornone(flag_t inflags, const flag *flaglist) {
95 static char buf[34];
96 int i;
97 char *ch=buf;
98
99 *ch++='+';
100
101 for (i=0;flaglist[i].flagchar!='\0' && i<32;i++) {
102 if (inflags&flaglist[i].flagbit) {
103 *ch++=flaglist[i].flagchar;
104 }
105 }
106
107 *ch='\0';
108 if (ch==(buf+1)) /* No flags set */
109 return "none";
110
111 return buf;
112 }
113 /* ugh */
114
115 char *printflags_noprefix(flag_t inflags, const flag *flaglist) {
116 static char buf[34];
117 int i;
118 char *ch=buf;
119
120 for (i=0;flaglist[i].flagchar!='\0' && i<32;i++) {
121 if (inflags&flaglist[i].flagbit) {
122 *ch++=flaglist[i].flagchar;
123 }
124 }
125
126 *ch='\0';
127 return buf;
128 }
129
130
131
132 /*
133 * printflagdiff:
134 * Prints the flag changes needed to change "oldflags" into "newflags"
135 */
136
137 char *printflagdiff(flag_t oldflags, flag_t newflags, const flag *flaglist) {
138 static char buf[40];
139 int i;
140 char *ch=buf;
141 int chd=0;
142
143 /* Removes first */
144
145 for (i=0;flaglist[i].flagchar!='\0' && i<32;i++) {
146 if ((oldflags & flaglist[i].flagbit) && !(newflags & flaglist[i].flagbit)) {
147 if (chd==0) {
148 chd=1;
149 *ch++='-';
150 }
151 *ch++=flaglist[i].flagchar;
152 }
153 }
154
155 /* Now adds */
156 chd=0;
157
158 for (i=0;flaglist[i].flagchar!='\0' && i<32;i++) {
159 if (!(oldflags & flaglist[i].flagbit) && (newflags & flaglist[i].flagbit)) {
160 if (chd==0) {
161 chd=1;
162 *ch++='+';
163 }
164 *ch++=flaglist[i].flagchar;
165 }
166 }
167
168 *ch='\0';
169 return buf;
170 }