예제 #1
0
static array<tree>
upgrade_brackets (array<tree> a, int level) {
  array<int> tp= symbol_types (a);
  //cout << "Upgrade " << a << ", " << tp << "\n";
  if (admits_brackets (tp)) {
    //cout << "  Downgrade dubious\n";
    array<tree> r= simplify_matching (a, downgrade_dubious (tp), level);
    if (r != a) return upgrade_brackets (r, level);
    //cout << "  Detect french\n";
    r= simplify_matching (a, detect_french_interval (a, tp), level);
    if (r != a) return upgrade_brackets (r, level);
    //cout << "  Detect absolute 1\n";
    r= simplify_matching (a, detect_absolute (a, tp, false), level);
    if (r != a) return upgrade_brackets (r, level);
    //cout << "  Detect absolute 2\n";
    r= simplify_matching (a, detect_absolute (a, tp, true), level);
    if (r != a) return upgrade_brackets (r, level);
    //cout << "  Detect probable\n";
    r= simplify_matching (a, detect_probable (a, tp), level);
    if (r != a) return upgrade_brackets (r, level);
    //cout << "  Detect dummy substitution\n";
    if (replace_dummies (a) != a) {
      array<tree> a2= replace_dummies (a);
      array<int> tp2= symbol_types (a2);
      r= simplify_matching (a2, detect_probable (a2, tp2), level);
      if (r != a2) return upgrade_brackets (r, level);
    }
    //cout << "  Confirm all\n";
    r= simplify_matching (a, confirm_all (tp), level);
    if (r != a) return upgrade_brackets (r, level);
    //cout << "  Missing left\n";
    if (get_preference ("automatic brackets") != "off")
      r= add_missing_left (a, tp);
    if (r != a) return upgrade_brackets (r, level);
    //cout << "  Missing right\n";
    if (get_preference ("automatic brackets") != "off")
      r= add_missing_right (a, tp);
    if (r != a) return upgrade_brackets (r, level);
  }
  if (admits_bigops (tp)) {
    array<tree> r= prefix_split (a, tp, level);
    if (r != a) return upgrade_brackets (r, level);
    r= infix_split (a, tp, symbol_priorities (a), level);
    if (r != a) return upgrade_brackets (r, level);
    r= postfix_split (a, tp, level);
    if (r != a) return upgrade_brackets (r, level);
    ASSERT (tp[0] == SYMBOL_OPEN_BIG, "invalid situation");
    r= upgrade_brackets (range (a, 1, N(a)), level + 1);
    tree body= concat_recompose (r);
    r= array<tree> ();
    r << make_around (a[0], body);
    return r;
  }
  return a;
}
예제 #2
0
int rx_mode(message pkt, int b)
{
	// MODE <nick> ({\+|-}{i|w|o|O|r}*)*
	// or MODE <channel> {[\+|-]|o|p|s|i|t|n|b|v} [<limit>] [<user>] [<ban mask>]
	int fd=bufs[b].handle;
	// If appropriate, trigger auto-join
	servlist *serv=bufs[b].autoent;
	if(autojoin && serv && serv->chans && !serv->join)
	{
		chanlist *curr=serv->chans;
		while(curr)
		{
			char joinmsg[8+strlen(curr->name)];
			sprintf(joinmsg, "JOIN %s %s", curr->name, curr->key?curr->key:"");
			irc_tx(fd, joinmsg);
			char jmsg[16+strlen(curr->name)];
			sprintf(jmsg, "auto: Joining %s", curr->name);
			add_to_buffer(b, JOIN, QUIET, 0, true, jmsg, "");
			curr=curr->next;
		}
		serv->join=true;
	}
	if(pkt.nargs<2)
	{
		e_buf_print(b, ERR, pkt, "Not enough arguments: ");
		return(0);
	}
	char *from, *user, *host;
	prefix_split(pkt.prefix, &from, &user, &host);
	for(int b2=0;b2<nbufs;b2++)
	{
		if((bufs[b2].type==CHANNEL)&&(bufs[b2].server==b)&&(irc_strcasecmp(pkt.args[0], bufs[b2].bname, bufs[b].casemapping)==0))
		{
			bool plus=false;
			switch(*pkt.args[1])
			{
				case '+':
					plus=true;
				case '-':; /* fallthrough */
					unsigned int i;
					for(i=0;i<bufs[b].npfx;i++)
					{
						if(bufs[b].prefixes[i].letter==pkt.args[1][1])
						{
							// user expected
							if(pkt.nargs<3)
							{
								e_buf_print(b, ERR, pkt, "Not enough arguments: ");
								return(0);
							}
							name *curr=bufs[b2].nlist;
							while(curr)
							{
								if(irc_strcasecmp(curr->data, pkt.args[2], bufs[b].casemapping)==0)
								{
									bool found=false;
									for(unsigned int j=0;j<curr->npfx;j++)
									{
										if(curr->prefixes[j].letter==pkt.args[1][1])
										{
											if(plus)
												found=true;
											else
											{
												curr->npfx--;
												for(unsigned int k=j;k<curr->npfx;k++)
													curr->prefixes[k]=curr->prefixes[k+1];
												if(curr==bufs[b2].us)
												{
													char ms[curr->npfx?curr->npfx+1:2];
													if(curr->npfx)
													{
														for(unsigned int i=0;i<curr->npfx;i++)
															ms[i]=curr->prefixes[i].letter;
														ms[curr->npfx]=0;
													}
													else
													{
														ms[0]='-';
														ms[1]=0;
													}
													char mm[24+strlen(curr->data)+strlen(ms)+strlen(from)];
													sprintf(mm, "You (%s) are now mode %s (%s)", curr->data, ms, from);
													add_to_buffer(b2, MODE, NORMAL, 0, false, mm, "");
												}
												else
												{
													char ms[curr->npfx?curr->npfx+1:2];
													if(curr->npfx)
													{
														for(unsigned int i=0;i<curr->npfx;i++)
															ms[i]=curr->prefixes[i].letter;
														ms[curr->npfx]=0;
													}
													else
													{
														ms[0]='-';
														ms[1]=0;
													}
													char mm[16+strlen(ms)+strlen(from)];
													sprintf(mm, " is now mode %s (%s)", ms, from);
													add_to_buffer(b2, MODE, NORMAL, 0, false, mm, curr->data);
												}
											}
										}
									}
									if(plus&&!found)
									{
										unsigned int n=curr->npfx++;
										prefix *pfx=realloc(curr->prefixes, curr->npfx*sizeof(prefix));
										if(pfx)
											(curr->prefixes=pfx)[n]=bufs[b].prefixes[i];
										else
											curr->npfx=n; // XXX silent fail
										if(curr==bufs[b2].us)
										{
											char ms[curr->npfx?curr->npfx+1:2];
											if(curr->npfx)
											{
												for(unsigned int i=0;i<curr->npfx;i++)
													ms[i]=curr->prefixes[i].letter;
												ms[curr->npfx]=0;
											}
											else
											{
												ms[0]='-';
												ms[1]=0;
											}
											char mm[24+strlen(curr->data)+strlen(ms)+strlen(from)];
											sprintf(mm, "You (%s) are now mode %s (%s)", curr->data, ms, from);
											add_to_buffer(b2, MODE, NORMAL, 0, false, mm, "");
										}
										else
										{
											char ms[curr->npfx?curr->npfx+1:2];
											if(curr->npfx)
											{
												for(unsigned int i=0;i<curr->npfx;i++)
													ms[i]=curr->prefixes[i].letter;
												ms[curr->npfx]=0;
											}
											else
											{
												ms[0]='-';
												ms[1]=0;
											}
											char mm[16+strlen(ms)+strlen(from)];
											sprintf(mm, " is now mode %s (%s)", ms, from);
											add_to_buffer(b2, MODE, NORMAL, 0, false, mm, curr->data);
										}
									}
									break;
								}
								curr=curr->next;
							}
							if(!curr)
								e_buf_print(b, ERR, pkt, "No such nick: ");
							break;
						}
					}
					if(i==bufs[b].npfx)
					{
						// it's a channel mode
						bool found=false;
						for(i=0;i<bufs[b2].npfx;i++)
						{
							if(bufs[b2].prefixes[i].letter==pkt.args[1][1])
							{
								if(plus)
									found=true;
								else
								{
									bufs[b2].npfx--;
									for(unsigned int j=i;j<bufs[b2].npfx;j++)
										bufs[b2].prefixes[j]=bufs[b2].prefixes[j+1];
									char ms[bufs[b2].npfx?bufs[b2].npfx+1:2];
									if(bufs[b2].npfx)
									{
										for(unsigned int i=0;i<bufs[b2].npfx;i++)
											ms[i]=bufs[b2].prefixes[i].letter;
										ms[bufs[b2].npfx]=0;
									}
									else
									{
										ms[0]='-';
										ms[1]=0;
									}
									char mm[16+strlen(ms)+strlen(from)];
									sprintf(mm, " is now mode %s (%s)", ms, from);
									add_to_buffer(b2, MODE, QUIET, 0, false, mm, bufs[b2].bname);
								}
							}
						}
						if(plus&&!found)
						{
							unsigned int n=bufs[b2].npfx++;
							prefix *pfx=realloc(bufs[b2].prefixes, bufs[b2].npfx*sizeof(prefix));
							if(pfx)
								(bufs[b2].prefixes=pfx)[n]=(prefix){.letter=pkt.args[1][1], .pfx=0}; // channel modes don't have associated prefixes
							else
								bufs[b2].npfx=n; // XXX silent fail
							char ms[bufs[b2].npfx?bufs[b2].npfx+1:2];
							if(bufs[b2].npfx)
							{
								for(unsigned int i=0;i<bufs[b2].npfx;i++)
									ms[i]=bufs[b2].prefixes[i].letter;
								ms[bufs[b2].npfx]=0;
							}
							else
							{
								ms[0]='-';
								ms[1]=0;
							}
							char mm[16+strlen(ms)+strlen(from)];
							sprintf(mm, " is now mode %s (%s)", ms, from);
							add_to_buffer(b2, MODE, QUIET, 0, false, mm, bufs[b2].bname);
						}
					}
				break;
				default:
					e_buf_print(b, ERR, pkt, "Malformed modespec - missing +/-: ");
				break;
			}