static bool
addrtype_mt_v1(const struct sk_buff *skb, struct xt_action_param *par)
{
	struct net *net = dev_net(par->in ? par->in : par->out);
	const struct xt_addrtype_info_v1 *info = par->matchinfo;
	const struct iphdr *iph;
	const struct net_device *dev = NULL;
	bool ret = true;

	if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_IN)
		dev = par->in;
	else if (info->flags & XT_ADDRTYPE_LIMIT_IFACE_OUT)
		dev = par->out;

#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
	if (par->family == NFPROTO_IPV6)
		return addrtype_mt6(net, dev, skb, info);
#endif
	iph = ip_hdr(skb);
	if (info->source)
		ret &= match_type(net, dev, iph->saddr, info->source) ^
		       (info->flags & XT_ADDRTYPE_INVERT_SOURCE);
	if (ret && info->dest)
		ret &= match_type(net, dev, iph->daddr, info->dest) ^
		       !!(info->flags & XT_ADDRTYPE_INVERT_DEST);
	return ret;
}
static int match(const struct sk_buff *skb,
		 const struct net_device *in, const struct net_device *out,
		 const struct xt_match *match, const void *matchinfo,
		 int offset, unsigned int protoff, int *hotdrop)
{
	const struct ipt_addrtype_info *info = matchinfo;
	const struct iphdr *iph = skb->nh.iph;
	int ret = 1;

	if (info->source)
		ret &= match_type(iph->saddr, info->source)^info->invert_source;
	if (info->dest)
		ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
	
	return ret;
}
// Grammar match: argument = type argument [= const_value]
bool match_argument(TokenState& state, Argument *ptr_argument)
{
    Type type;
    if (!match_type(state, &type))
    {
        state.error_msg += "Expect type for argument.\n";
        return false;
    }

    simple::string name;
    if (!match_ident_name(state, &name))
    {
        state.error_msg += "Expect name for argument.\n";
        return false;
    }

    bool has_default = false;
    simple::string token;
    if (state.peek_token(&token) && token == "=")
    {
        if (!match_constant(state))
        {
            state.error_msg += "Expect constant as default value of argument.\n";
            return false;
        }
    }

    ptr_argument->type = type;
    ptr_argument->has_default = has_default;
    ptr_argument->name = name;
    return true;
}
/*
parse_int

Matches a valid integer expression by looking ahead one token

Parameters: none

Return: none
*/
void parse_int(Tree &cst){
	cst.add_branch_node("int");

	std::vector<Token>::iterator next_token = std::next(curr_token, 1);

	if(!(next_token -> type).compare("plus")){
		match_type("digit", cst);
		match("+", cst);
		parse_expr(cst);
	}
	else{
		match_type("digit", cst);
	}

	cst.kill_all_children();
}
Exemple #5
0
Parsed parse_thrift(const std::string& filename, Parsed& parsed)
{
  std::ifstream in(filename);

  std::string ns;
  std::vector<std::string> types;
  for (std::string s; std::getline(in, s); )
  {
    auto ret_ns = match_ns(s);
    if (ret_ns)
    {
      assert(ns.empty());
      assert(types.empty());
      ns = *ret_ns;
      continue;
    }

    auto ret_type = match_type(s);
    if (ret_type)
    {
      types.push_back(*ret_type);
      continue;
    }
  }

  std::copy(begin(types), end(types), std::back_inserter(parsed[ns]));

  return parsed;
}
Exemple #6
0
/*
 *		parse top level declarations
 */
long dodcls (long stclass, TAG_SYMBOL *mtag, int is_struct)
{
	long err;
	struct type t;

	blanks();

	if (match_type(&t, NO, YES)) {
		if (t.type == CSTRUCT && t.otag == -1)
			t.otag = define_struct(t.sname, stclass, !!(t.flags & F_STRUCT));
		else if (t.type == CENUM) {
			if (t.otag == -1)
				t.otag = define_enum(t.sname, stclass);
			t.type = enum_types[t.otag].base;
		}
		err = declglb(t.type, stclass, mtag, t.otag, is_struct);
	}
	else if (stclass == PUBLIC)
		return (0);
	else
		err = declglb(CINT, stclass, mtag, NULL_TAG, is_struct);

	if (err == 2)	/* function */
		return (1);
	else if (err) {
		kill();
		return (0);
	}
	else
		ns();
	return (1);
}
Exemple #7
0
static bool
addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
{
	const struct ipt_addrtype_info *info = par->matchinfo;
	const struct iphdr *iph = ip_hdr(skb);
	bool ret = true;

	if (info->source)
		ret &= match_type(NULL, iph->saddr, info->source) ^
		       info->invert_source;
	if (info->dest)
		ret &= match_type(NULL, iph->daddr, info->dest) ^
		       info->invert_dest;

	return ret;
}
Exemple #8
0
void dotypedef (void)
{
	struct type t;

	if (!match_type(&t, YES, NO)) {
		error("unknown type");
		kill();
		return;
	}
	if (t.type == CENUM) {
		if (t.otag == -1) {
			if (user_short_enums)
				warning(W_GENERAL,
					"typedef to undefined enum; "
					"assuming base type int");
			t.type = CINT;
		}
		else
			t.type = enum_types[t.otag].base;
	}
	if (!symname(t.sname)) {
		error("invalid type name");
		kill();
		return;
	}
	typedefs = realloc(typedefs, (typedef_ptr + 1) * sizeof(struct type));
	typedefs[typedef_ptr++] = t;
	ns();
}
static bool
addrtype_mt_v0(const struct sk_buff *skb, struct xt_action_param *par)
{
	struct net *net = dev_net(par->in ? par->in : par->out);
	const struct xt_addrtype_info *info = par->matchinfo;
	const struct iphdr *iph = ip_hdr(skb);
	bool ret = true;

	if (info->source)
		ret &= match_type(net, NULL, iph->saddr, info->source) ^
		       info->invert_source;
	if (info->dest)
		ret &= match_type(net, NULL, iph->daddr, info->dest) ^
		       info->invert_dest;

	return ret;
}
Exemple #10
0
static bool
set_match_type( int argc, char *argv[] ) {
  int i;
  const char *service_name;
  for ( i = 1; i < argc; i++ ) {
    if ( ( service_name = match_type( LLDP_PACKET_IN, argv[ i ] ) ) != NULL ) {
      register_dl_type_filter( ETH_ETHTYPE_LLDP, OFP_DEFAULT_PRIORITY, service_name );
    }
    else if ( ( service_name = match_type( ANY_PACKET_IN, argv[ i ] ) ) != NULL ) {
      register_any_filter( 0, service_name );
    }
    else {
      return false;
    }
  }

  return true;
}
Exemple #11
0
/*
parse_char_list

Checks the current token for a char and recursively iterates the next tokens
for chars

Parameters: none

Return: none
*/
void parse_char_list(Tree &cst){
	cst.add_branch_node("char_list");
	if (!(curr_token -> type).compare("identifier")){
		match_type("identifier", cst);
		parse_char_list(cst);
	}
	else if(!(curr_token -> type).compare("keyword")){
		match_type("keyword", cst);
		parse_char_list(cst);
	}
	else if (!(curr_token -> type).compare("space")){
		match(" ", cst);
		parse_char_list(cst);
	}
	else{
		// ε production, do nothing
	}
	cst.kill_all_children();
}
Exemple #12
0
static bool
addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in,
           const struct net_device *out, const struct xt_match *match,
           const void *matchinfo, int offset, unsigned int protoff,
           bool *hotdrop)
{
    const struct ipt_addrtype_info *info = matchinfo;
    const struct iphdr *iph = ip_hdr(skb);
    bool ret = true;

    if (info->source)
        ret &= match_type(NULL, iph->saddr, info->source) ^
               info->invert_source;
    if (info->dest)
        ret &= match_type(NULL, iph->daddr, info->dest) ^
               info->invert_dest;

    return ret;
}
Exemple #13
0
static bool
set_match_type( int argc, char *argv[], services *services ) {
  create_list( &services->arp_or_unicast );
  create_list( &services->broadcast );
  int i;
  char *service_name;
  for ( i = 1; i < argc; i++ ) {
    if ( ( service_name = match_type( ARP_OR_UNICAST, argv[ i ] ) ) != NULL ) {
      append_to_tail( &services->arp_or_unicast, service_name );
    }
    else if ( ( service_name = match_type( BROADCAST, argv[ i ] ) ) != NULL ) {
      append_to_tail( &services->broadcast, service_name );
    }
    else {
      return false;
    }
  }

  return true;
}
match_string::match_type
match_string::match(part_iterator &begin, const part_iterator &end) const {
  bool matches = false;
  if (begin != end) {
    std::string bit = *begin;
    matches = bit == str;
    ++begin;
  }
  if (!matches) { throw error(); }
  return match_type();
}
Exemple #15
0
static bool
addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
{
	const struct ipt_addrtype_info_v1 *info = par->matchinfo;
	const struct iphdr *iph = ip_hdr(skb);
	const struct net_device *dev = NULL;
	bool ret = true;

	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)
		dev = par->in;
	else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)
		dev = par->out;

	if (info->source)
		ret &= match_type(dev, iph->saddr, info->source) ^
		       (info->flags & IPT_ADDRTYPE_INVERT_SOURCE);
	if (ret && info->dest)
		ret &= match_type(dev, iph->daddr, info->dest) ^
		       !!(info->flags & IPT_ADDRTYPE_INVERT_DEST);
	return ret;
}
match_name::match_type
match_name::match(part_iterator &begin, const part_iterator &end) const {
  if (begin != end) {
    try {
      std::string bit = *begin++;
      return match_type(bit);
    } catch (std::exception &e) {
      throw error();
    }
  }
  throw error();
}
Exemple #17
0
/*
parse_bool

Matches a valid boolean expression by looking ahead one token

Parameters: none

Return: none
*/
void parse_bool(Tree &cst){
	cst.add_branch_node("boolean");
	if(!(curr_token -> type).compare("open_paren")){
		match_type("open_paren", cst);
		parse_expr(cst);
		match(boolop, cst);
		parse_expr(cst);
		match(")", cst);
	}
	else{
		match(boolval, cst);
	}
	cst.kill_all_children();
}
match_int::match_type
match_int::match(part_iterator &begin, const part_iterator &end) const {
  if (begin != end) {
    try {
      std::string bit = *begin;
      int x = boost::lexical_cast<int>(bit);
      ++begin;
      return match_type(x);
    } catch (std::exception &e) {
      throw error();
    }
  }
  throw error();
}
Exemple #19
0
static bool
addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
           const struct net_device *out, const struct xt_match *match,
           const void *matchinfo, int offset, unsigned int protoff,
           bool *hotdrop)
{
    const struct ipt_addrtype_info_v1 *info = matchinfo;
    const struct iphdr *iph = ip_hdr(skb);
    const struct net_device *dev = NULL;
    bool ret = true;

    if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)
        dev = in;
    else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)
        dev = out;

    if (info->source)
        ret &= match_type(dev, iph->saddr, info->source) ^
               (info->flags & IPT_ADDRTYPE_INVERT_SOURCE);
    if (ret && info->dest)
        ret &= match_type(dev, iph->daddr, info->dest) ^
               (info->flags & IPT_ADDRTYPE_INVERT_DEST);
    return ret;
}
Exemple #20
0
// Grammar match
bool match_prototype(TokenState& state, Prototype *ptr_prototype)
{
    Type ret_type;
    if (! match_type(state, &ret_type))
    {
        state.error_msg += "Expected return type for prototype.\n";
        return false;
    }

    simple::string fun_name;
    if (!match_ident_name(state, &fun_name))
    {
        state.error_msg += "Expected function name.\n";
        return false;
    }

    if (!match_word(state, "("))
    {
        state.error_msg += "Missed ( after function name.\n";
        return false;
    }

    ArgumentsList argument_list;
    if (!match_arguments_list(state, &argument_list))
        return false;

    // Skip ;
    simple::string token;
    if (state.peek_token(&token) && token == ";")
        state.skip();

    if (state.peek_token(&token))
    {
        state.error_msg.snprintf("There are some words(\"%s\") following prototype.", 256,
                                 token.c_str());
        return false;
    }

    ptr_prototype->fun_name = simple::move(fun_name);
    ptr_prototype->ret_type = simple::move(ret_type);
    ptr_prototype->arguments_list = simple::move(argument_list);
    return true;
}
Exemple #21
0
match_osm_id::match_type match_osm_id::match(part_iterator &begin,
                                             const part_iterator &end) const {
  if (begin != end) {
    try {
      std::string bit = *begin;
      // note that osm_id_t is actually unsigned, so we lose a bit of
      // precision here, but it's OK since IDs are postgres 'bigint' types
      // which are also signed, so element 2^63 is unlikely to exist.
      int64_t x = boost::lexical_cast<int64_t>(bit);
      if (x > 0) {
        ++begin;
        return match_type(x);
      }
    } catch (std::exception &e) {
      throw error();
    }
  }
  throw error();
}
Exemple #22
0
vm_offset_t
db_disasm(vm_offset_t loc, bool altfmt)
{
	struct riscv_op *op;
	InstFmt i;
	int j;

	i.word = db_get_value(loc, INSN_SIZE, 0);

	/* First match opcode */
	for (j = 0; riscv_opcodes[j].name != NULL; j++) {
		op = &riscv_opcodes[j];
		if (op->opcode == i.RType.opcode) {
			if (match_type(i, op, loc))
				break;
		}
	}

	db_printf("\n");
	return(loc + INSN_SIZE);
}
Exemple #23
0
static int read_file_list(const char * path, solist_t files, solist_t dirs)
{
	int ret;
	struct dirent **namelist;
	strobj_t sobj = NULL;
	const char * errmsg;

	struct stat st;
	char buf[1024];

	//d_dbg("%s: path = %s\n",__func__, path);
	ret = scandir(path, &namelist, 0, alphasort);
	if (ret < 0) perror("scandir");
	else
	{
		while (ret > 0)
		{
			ret--;
			errmsg = NULL;
#if 1//marco, use lstat to retrieve the file type of the files under 'path'
	//in previous version, we use d_type to know the file_type but some filesystem
	//doesn't support it, so the values will always 0 and become DT_UNKNOWN
			sprintf(buf,"%s/%s",path,namelist[ret]->d_name);
			lstat(buf, &st);
			if (S_ISLNK(st.st_mode))
			{
				errmsg = "link";
				goto ERR;
			}
			else if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))
			{
				if (namelist[ret]->d_name[0]=='.')
				{
					errmsg = "hidden";
					goto ERR;
					//	break;
				}
				if (S_ISREG(st.st_mode) && !match_type(namelist[ret]->d_name))
				{
					errmsg = "unmatch";
					goto ERR;
					//	break;
				}
				sobj = sobj_new();
				if (sobj)
				{
					sobj_add_string(sobj, path);
					sobj_add_char(sobj, '/');
					sobj_add_string(sobj, namelist[ret]->d_name);
					verbose("Found %s file - '%s'\n",
						( S_ISDIR(st.st_mode)) ? "DT_DIR":"DT_REG",
						sobj_get_string(sobj));
					solist_add( (S_ISDIR(st.st_mode))?dirs : files, sobj);
				}
				else
				{
					verbose("Memory allocation failed !!\n");
				}
			}
			else
			{
				errmsg = "UNKNOWN FILE TYPE";				
			}	
ERR:			
#else				
			switch (namelist[ret]->d_type)
			{
			case DT_UNKNOWN:	errmsg = "DT_UNKNOWN";	break;
			case DT_FIFO:		errmsg = "DT_FIFO";		break;
			case DT_CHR:		errmsg = "DT_CHR";		break;
			case DT_BLK:		errmsg = "DT_BLK";		break;
			case DT_LNK:		errmsg = "DT_LNK";		break;
			case DT_SOCK:		errmsg = "DT_SOCK";		break;
			case DT_WHT:		errmsg = "DT_WHT";		break;

			case DT_DIR:
			case DT_REG:
				if (namelist[ret]->d_name[0]=='.')
				{
					errmsg = "hidden";
					break;
				}
				if (namelist[ret]->d_type==DT_REG && !match_type(namelist[ret]->d_name))
				{
					errmsg = "unmatch";
					break;
				}
				sobj = sobj_new();
				if (sobj)
				{
					sobj_add_string(sobj, path);
					sobj_add_char(sobj, '/');
					sobj_add_string(sobj, namelist[ret]->d_name);
					verbose("Found %s file - '%s'\n",
						(namelist[ret]->d_type==DT_DIR) ? "DT_DIR":"DT_REG",
						sobj_get_string(sobj));
					solist_add((namelist[ret]->d_type == DT_DIR) ?
								dirs : files, sobj);
				}
				else
				{
					verbose("Memory allocation failed !!\n");
				}
				break;
			}
#endif			
			if (errmsg && o_verbose > 1)
			{
				verbose("Ignoring %s file - '%s'\n",
					errmsg, namelist[ret]->d_name);
			}
			free(namelist[ret]);
		}
		free(namelist);
	}
	//d_dbg("%s: return %d\n",__func__,ret);
	return ret;
}
void l_scan (SOURCE_FILE * sf)
{
	int r = 1,in_sub = FALSE;
	int block_stack[STACK_SIZE],block_size = 0;

	list_init(&list_sub);
	list_init(&list_var);
	list_init(&list_array);

	while(r)
	{
		r = l_get_line(sf);
		pline = line;
		l_get_token ();
		// skip empty line
		if (token_type==TT_LINE_END) continue;
		// check command
		if (IS_KEYWORD(token_type))
		{
			if (token_type==KEY_SUB)
			{
				USER_SUB * sub;
				
				if(in_sub)
				{
					merror_msg("sub procedure can not be nested");
				}
				in_sub = TRUE;

				match_type(TT_ID);
				sub = (USER_SUB*)calloc(sizeof(USER_SUB),1);
				sub->name	= s_strdup(token);
				sub->pos	= sf->pos;
				list_push(&list_sub,sub);
				match_type(TT_LINE_END);
				push_block(B_SUB);
				continue;
			}
			else if (token_type==KEY_END)
			{
				if (block_size<=0 || block_top==B_REPEAT)
					merror_illegal_token();
				match_type(TT_LINE_END);
				if(pop_block==B_SUB)
				{
					in_sub = FALSE;
				}
				continue;
			}
			else if(token_type==KEY_VAR)
			{
				while(1)
				{
					match_type(TT_ID);
					l_get_token();
					if (token_type==TT_END)			break;
					else if (token_type==TT_COM)	continue;
					else 							merror_illegal_token();
				}
			}
			if (!in_sub) merror_illegal_token();
			if(token_type==KEY_IF)
			{
				match_exp(pline);
				match_type(TT_LINE_END);
				push_block(B_IF);
			}
			else if (token_type==KEY_ELSEIF)
			{
				if (block_size<=0 || block_top!=B_IF)
					merror_illegal_token();
				match_exp(pline);
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_ELSE)
			{
				if (block_size<=0 || !(block_top==B_IF || block_top==B_CASE))
					merror_illegal_token();
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_WHILE)
			{
				match_exp(pline);
				match_type(TT_LINE_END);
				push_block(B_WHILE);
			}
			else if (token_type==KEY_FOR)
			{
				// 'for' ID '=' EXP 'to' EXP
				match_type(TT_ID);
				match_type(OPR_EQ);
				match_exp(pline);
				match_str("to");
				match_exp(pline);
				l_get_token();
				if (token_type!=TT_LINE_END)
				{
					if (!str_eq(token,"step"))
						merror_expect("step");
					match_exp(pline);
					match_type(TT_LINE_END);
				}
				push_block(B_FOR);
			}
			else if (token_type==KEY_CASE)
			{
				match_type(TT_ID);
				match_type(TT_LINE_END);
				push_block(B_CASE);
			}
			else if (token_type==KEY_REPEAT)
			{
				match_type(TT_LINE_END);
				push_block(B_REPEAT);
			}
			else if (token_type==KEY_UNTIL)
			{
				if (block_size<=0 || block_top!=B_REPEAT)
					merror_illegal_token();
				match_exp(pline);
				match_type(TT_LINE_END);
				pop_block;
			}
			else if (token_type==KEY_WHEN)
			{
				if (block_size<=0 || block_top!=B_CASE)
					merror_illegal_token();
				match_exp(pline);
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_GOSUB)
			{
				match_type(TT_ID);
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_EXIT)
			{
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_BREAK)
			{
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_RETURN)
			{
				match_type(TT_LINE_END);
			}
			else if (token_type==KEY_DIM)
			{
				while(1)
				{
					match_type	(TT_ID);
					match_type	(TT_LBK);
					match_exp	(pline);
					match_type	(TT_RBK);
					l_get_token();
					if		(token_type==TT_COM)		continue;
					else if	(token_type==TT_LINE_END)	break;
					else								merror_illegal_token();
				}
			}
		}
		else if (token_type==TT_ID)
		{
			if (!in_sub) merror_illegal_token();
			if (str_eq(token,"print"))
			{
				while(1)
				{
					l_get_token();
					if(token_type!=TT_STRING)
					{
						l_put_back();
						match_exp(pline);
					}
					l_get_token();
					if(token_type==TT_LINE_END) break;
					else if (token_type==TT_COM) continue;
					else merror_expect(",");
				}
			}
			else if (str_eq(token,"input"))
			{
				while(1)
				{
					match_type(TT_ID);
					l_get_token();
					if(token_type==TT_LINE_END) break;
					else if (token_type==TT_COM) continue;
					else merror_expect(",");
				}
			}
			else
			{	// match: [var][=][exp]
				l_get_token();
				if (token_type==OPR_EQ)
				{
					match_exp(pline);
					match_type(TT_LINE_END);
				}
				else
				{
					if (token_type!=TT_LBK)merror_expect("(");
					match_exp(pline);
					match_type(TT_RBK);
					match_type(OPR_EQ);
					match_exp(pline);
					match_type(TT_LINE_END);
				}
			}
		}
		else 
			merror_illegal_token ();
	}
	if (block_size>0)
		merror_msg("incompleted '%s' block!",BLOCK_NAME[block_top]);
}
match_begin::match_type
match_begin::match(part_iterator &begin, const part_iterator &end) const {
  return match_type();
}
bool MethodIG::Arg::parse( iglexer& lex, bool argname )
{
    //arg: [ifc_in|ifc_out|ifc_inout|] [const] type  
    //type: [class[<templarg>]::]* type[<templarg>] [[*|&] [const]]*

    int io = lex.matches_either("ifc_in","ifc_out","ifc_inout","ifc_ret");
    if(!io) io=1;

    //ifc_return(ifcname)
    if(io == 4) {
        lex.match('(');
        match_type(lex, ifctarget);
        lex.match(')');

        io = 2;
    }

    binarg = (io&1) != 0;
    boutarg = (io&2) != 0;

    bvolatile = lex.matches("ifc_volatile");

    bconst = lex.matches("const");
    benum = lex.matches("enum");

    if(lex.matches("unsigned"))
        type << "unsigned" << ' ';

    match_type(lex, type);

    int isPR=0,wasPR;
    int isCV=0;

    while((wasPR = lex.matches_either('*', '&')))
    {
        isPR = wasPR;
        if(bconst) {
            //const is a part of the inner type
            type.ins(0, "const ");
            bconst = 0;
        }

        type << lex.last().value();

        if((isCV = lex.matches_either("const", "volatile")))
            type << ' ' << lex.last().value();
    }

    if(isCV == 1)   //ends with const
        bconst = true;
    if(isCV)
        type.resize(isCV==1 ? 6 : 9);   //strip the last const and volatile

    bptr = isPR == 1;
    bref = isPR == 2;

    if(boutarg && ((!bptr && !bref && !ifctarget) || type.begins_with("const "))) {
        lex.set_err() << "out argument must be a ref or ptr and cannot be const\n";
    }

    basetype = type;
    if(isPR)
        basetype.shift_end(-1);

    if(basetype.begins_with("const ")) basetype.shift_start(6);
    else if(basetype.ends_with(" const")) basetype.shift_end(-6);

    //special handling for strings and tokens
    if(type == "const char*") {
        basetype = "coid::charstr";
        base2arg = ".c_str()";
    }
    else if(basetype == "token" || basetype == "coid::token") {
        basetype = "coid::charstr";
    }

    biref = basetype.begins_with("iref<");
    if(biref) {
        token bs = basetype;
        bs.shift_start(5);
        bs.cut_right_back('>');

        do {
            token p = bs.cut_left("::", false);
            fulltype << p;
            if(bs)
                fulltype << '_';
        }
        while(bs);
    }
    else if(ifctarget)
        lex.set_err() << "ifc_ret argument must be an iref<>\n";

    if(ifctarget) {
        type.swap(ifctarget);
        type.ins(0, "iref<");
        type.append('>');
        basetype.set(type.ptr()+5, type.ptre()-1);

        //remove iref from ifctarget
        ifctarget.del(0, 5);
        ifctarget.del(-1, 1);
    }


    if(!argname)
        return lex.no_err();


    lex.match(lex.IDENT, name, "expecting argument name");
    
    //match array
    if(lex.matches('[') )
        size << lex.next_as_block(lex.SQUARE);

    bnojs = false;

    //match default value
    if(lex.matches('=')) {
        //match everything up to a comma or a closing parenthesis
        lex.enable(lex.SQUARE, true);
        lex.enable(lex.ROUND, true);
        do {
            const lexer::lextoken& tok = lex.next();
            
            if( tok == lex.SQUARE || tok == lex.ROUND ) {
                lex.complete_block();
                defval << tok.leading_token(lex) << tok << tok.trailing_token(lex);
                continue;
            }
            if( tok == ','  ||  tok == ')'  ||  tok.end() ) {
                lex.push_back();
                break;
            }

            defval << tok;
        }
        while(1);
        lex.enable(lex.SQUARE, false);
        lex.enable(lex.ROUND, false);

        bnojs = name.first_char() == '_';
    }

    return lex.no_err();
}
Exemple #27
0
/*
parse_identifier

Matches a valid variable name

Parameters: none

Return: none
*/
void parse_identifier(Tree &cst){
	cst.add_branch_node("identifier");
	match_type("identifier", cst);
	cst.kill_all_children();
}