return NULL;
}
-// tidies up redundant modes, e.g. +nt-nt+i becomes +-+i,
-// a section further down the chain tidies up the +-+- crap.
+
+/** ModeParser::CompressModes()
+ * Tidies up redundant modes,
+ * e.g. +nt-nt+i becomes +-+i
+ * A section further down the chain tidies up the +-+- crap.
+ */
std::string ModeParser::CompressModes(std::string modes,bool channelmodes)
{
- int counts[127];
+ /*
+ * OK, iterate over the mode string and count how many times a certain mode appears in it.
+ * Then, erase all instances of any character that appears more than once.
+ * This only operates on modes with no parameters, you can still +v-v+v-v+v-v to your heart's content.
+ */
+
+ /* Do we really need an int here? Can you fit enough modes in a line to overflow a short? */
+ short counts[127];
bool active[127];
- memset(counts,0,sizeof(counts));
- memset(active,0,sizeof(active));
- for (unsigned int i = 0; i < modes.length(); i++)
+ memset(counts, 0, sizeof(counts));
+ memset(active, 0, sizeof(active));
+
+ for(unsigned char* i = (unsigned char*)modes.c_str(); *i; i++)
{
- if ((modes[i] == '+') || (modes[i] == '-'))
+ if((*i == '+') || (*i == '-'))
continue;
- if (channelmodes)
- {
- if ((strchr("itnmsp",modes[i])) || ((ModeDefined(modes[i],MT_CHANNEL)) && (ModeDefinedOn(modes[i],MT_CHANNEL)==0) && (ModeDefinedOff(modes[i],MT_CHANNEL)==0)))
- {
- log(DEBUG,"Tidy mode %c",modes[i]);
- counts[(unsigned int)modes[i]]++;
- active[(unsigned int)modes[i]] = true;
- }
- }
- else
+
+ if(!channelmodes || (channelmodes && (strchr("itnmsp", *i) || (ModeDefined(*i, MT_CHANNEL) && !ModeDefinedOn(*i,MT_CHANNEL) && !ModeDefinedOff(*i,MT_CHANNEL)))))
{
- log(DEBUG,"Tidy mode %c",modes[i]);
- counts[(unsigned int)modes[i]]++;
- active[(unsigned int)modes[i]] = true;
+ log(DEBUG,"Tidy mode %c", *i);
+ counts[*i]++;
+ active[*i] = true;
}
}
- for (int j = 65; j < 127; j++)
+
+ for(unsigned char j = 65; j < 127; j++)
{
if ((counts[j] > 1) && (active[j] == true))
{
- static char v[2];
- v[0] = (unsigned char)j;
- v[1] = '\0';
- std::string mode_str = v;
- std::string::size_type pos = modes.find(mode_str);
- if (pos != std::string::npos)
+ std::string::size_type pos;
+
+ while((pos = modes.find(j)) != std::string::npos)
{
- log(DEBUG,"all occurances of mode %c to be deleted...",(unsigned char)j);
- while (modes.find(mode_str) != std::string::npos)
- modes.erase(modes.find(mode_str),1);
- log(DEBUG,"New mode line: %s",modes.c_str());
+ log(DEBUG, "Deleting occurence of mode %c...", j);
+ modes.erase(pos, 1);
+ log(DEBUG,"New mode line: %s", modes.c_str());
}
}
}
+
return modes;
}
}
char outlist[MAXBUF];
+ char mlist[MAXBUF];
char *outpars[32];
int param = 2;
int pc = 0;
return;
}
- char* modelist = parameters[1]; /* mode list, e.g. +oo-o *
- * parameters[2] onwards are parameters for
- * modes that require them :) */
+ std::string tidied = this->CompressModes(parameters[1],true);
+ strlcpy(mlist,tidied.c_str(),MAXBUF);
+ char* modelist = mlist;
+
*outlist = *modelist;
char* outl = outlist+1;
log(DEBUG,"process_modes: modelist: %s",modelist);
- std::string tidied = this->CompressModes(modelist,true);
- strlcpy(modelist,tidied.c_str(),MAXBUF);
-
int len = tidied.length();
while (modelist[len-1] == ' ')
modelist[--len] = '\0';