Beispiel #1
0
void main()
  {
    printf( "%d\n", keyword_lookup( "case" ) );
    printf( "%d\n", keyword_lookup( "crigger" ) );
    printf( "%d\n", keyword_lookup( "auto" ) );
  }
int mail_index_sync_keywords(struct mail_index_sync_map_ctx *ctx,
			     const struct mail_transaction_header *hdr,
			     const struct mail_transaction_keyword_update *rec)
{
	struct mail_index_view *view = ctx->view;
	const char *keyword_name;
	const struct mail_index_ext *ext;
	const uint32_t *uid, *end;
	uint32_t seqset_offset, ext_map_idx;
	unsigned int keyword_idx;
	int ret;

	i_assert(rec->name_size > 0);

	seqset_offset = sizeof(*rec) + rec->name_size;
	if ((seqset_offset % 4) != 0)
		seqset_offset += 4 - (seqset_offset % 4);
	i_assert(seqset_offset < hdr->size);

	uid = CONST_PTR_OFFSET(rec, seqset_offset);
	end = CONST_PTR_OFFSET(rec, hdr->size);

	keyword_name = t_strndup(rec + 1, rec->name_size);
	if (!keyword_lookup(ctx, keyword_name, &keyword_idx))
		keywords_header_add(ctx, keyword_name, &keyword_idx);

	/* if the keyword wasn't found, the "keywords" extension was created.
	   if it was found, the record size should already be correct, but
	   in case it isn't just fix it ourself. */
	if (!mail_index_map_lookup_ext(view->map, MAIL_INDEX_EXT_KEYWORDS,
				       &ext_map_idx))
		i_unreached();

	ext = array_idx(&view->map->extensions, ext_map_idx);
	if (keyword_idx / CHAR_BIT >= ext->record_size) {
		if (rec->modify_type == MODIFY_REMOVE) {
			/* nothing to do */
			return 1;
		}

		/* grow the record size */
		keywords_ext_register(ctx, ext_map_idx, ext->reset_id,
				      ext->hdr_size,
				      array_count(&view->map->keyword_idx_map));
		if (!mail_index_map_lookup_ext(view->map,
					       MAIL_INDEX_EXT_KEYWORDS,
					       &ext_map_idx))
			i_unreached();
		ext = array_idx(&view->map->extensions, ext_map_idx);
	}

	while (uid+2 <= end) {
		ret = keywords_update_records(ctx, ext, keyword_idx,
					      rec->modify_type,
					      uid[0], uid[1]);
		if (ret <= 0)
			return ret;

		uid += 2;
	}

	return 1;
}
Beispiel #3
0
/* ---------------------------------------------------------------------
 * CMD_EVAL
 * This monster evaluates an if/or/and statement
 * There are five kinds of statement:
 * 1) keyword and value (no $-code)	    if random 30
 * 2) keyword, comparison and value	    if people > 2
 * 3) keyword and actor		    	    if isnpc $n
 * 4) keyword, actor and value		    if carries $n sword
 * 5) keyword, actor, comparison and value  if level $n >= 10
 *
 *----------------------------------------------------------------------
 */
int cmd_eval( sh_int vnum, char *line, int check,
	CHAR_DATA *mob, CHAR_DATA *ch, 
	const void *arg1, const void *arg2, CHAR_DATA *rch )
{
    CHAR_DATA *lval_char = mob;
    CHAR_DATA *vch = (CHAR_DATA *) arg2;
    OBJ_DATA *obj1 = (OBJ_DATA  *) arg1;
    OBJ_DATA *obj2 = (OBJ_DATA  *) arg2;
    OBJ_DATA  *lval_obj = NULL;

    char *original, buf[MAX_INPUT_LENGTH], code;
    int lval = 0, oper = 0, rval = -1;

    original = line;
    line = one_argument( line, buf );
    if ( buf[0] == '\0' || mob == NULL )
	return FALSE;

    /*
     * If this mobile has no target, let's assume our victim is the one
     */
    if ( mob->mprog_target == NULL )
	mob->mprog_target = ch;

    switch ( check )
    {
	/*
	 * Case 1: keyword and value
	 */
	case CHK_RAND:
	    return( atoi( buf ) < number_percent() );
	case CHK_MOBHERE:
	    if ( is_number( buf ) )
		return( get_mob_vnum_room( mob, atoi(buf) ) );
	    else
		return( (bool) (get_char_room( mob, buf) != NULL) );
	case CHK_OBJHERE:
	    if ( is_number( buf ) )
		return( get_obj_vnum_room( mob, atoi(buf) ) );
	    else
		return( (bool) (get_obj_here( mob, buf) != NULL) );
        case CHK_MOBEXISTS:
	    return( (bool) (get_char_world( mob, buf) != NULL) );
	case CHK_OBJEXISTS:
	    return( (bool) (get_obj_world( mob, buf) != NULL) );
	/*
	 * Case 2 begins here: We sneakily use rval to indicate need
	 * 		       for numeric eval...
	 */
	case CHK_PEOPLE:
	    rval = count_people_room( mob, 0 ); break;
	case CHK_PLAYERS:
	    rval = count_people_room( mob, 1 ); break;
	case CHK_MOBS:
	    rval = count_people_room( mob, 2 ); break;
	case CHK_CLONES:
	    rval = count_people_room( mob, 3 ); break;
	case CHK_ORDER:
	    rval = get_order( mob ); break;
	case CHK_HOUR:
	    rval = time_info.hour; break;
	default:;
    }

    /*
     * Case 2 continued: evaluate expression
     */
    if ( rval >= 0 )
    {
	if ( (oper = keyword_lookup( fn_evals, buf )) < 0 )
	{
	    sprintf( buf, "Cmd_eval: prog %d syntax error(2) '%s'",
		vnum, original );
	    bug( buf, 0 );
	    return FALSE;
	}
	one_argument( line, buf );
	lval = rval;
	rval = atoi( buf );
	return( num_eval( lval, oper, rval ) );
    }

    /*
     * Case 3,4,5: Grab actors from $* codes
     */
    if ( buf[0] != '$' || buf[1] == '\0' )
    {
	sprintf( buf, "Cmd_eval: prog %d syntax error(3) '%s'",
		vnum, original );
	bug( buf, 0 );
        return FALSE;
    }
    else
        code = buf[1];
    switch( code )
    {
    	case 'i':
            lval_char = mob; break;
        case 'n':
            lval_char = ch; break;
        case 't':
            lval_char = vch; break;
        case 'r':
            lval_char = rch == NULL ? get_random_char( mob ) : rch ; break;
        case 'o':
            lval_obj = obj1; break;
        case 'p':
            lval_obj = obj2; break;
	case 'q':
	    lval_char = mob->mprog_target; break;
	default:
	    sprintf( buf, "Cmd_eval: prog %d syntax error(4) '%s'",
		vnum, original );
	    bug( buf, 0 );
	    return FALSE;
    }
    /*
     * From now on, we need an actor, so if none was found, bail out
     */
    if ( lval_char == NULL && lval_obj == NULL )
    	return FALSE;

    /*
     * Case 3: Keyword, comparison and value
     */
    switch( check )
    {
	case CHK_ISPC:
            return( lval_char != NULL && !IS_NPC( lval_char ) );
        case CHK_ISNPC:
            return( lval_char != NULL && IS_NPC( lval_char ) );
        case CHK_ISGOOD:
            return( lval_char != NULL && IS_GOOD( lval_char ) );
        case CHK_ISEVIL:
            return( lval_char != NULL && IS_EVIL( lval_char ) );
        case CHK_ISNEUTRAL:
            return( lval_char != NULL && IS_NEUTRAL( lval_char ) );
	case CHK_ISIMMORT:
            return( lval_char != NULL && IS_IMMORTAL( lval_char ) );
        case CHK_ISCHARM: /* A relic from MERC 2.2 MOBprograms */
            return( lval_char != NULL && IS_AFFECTED( lval_char, AFF_CHARM ) );
        case CHK_ISFOLLOW:
            return( lval_char != NULL && lval_char->master != NULL 
		 && lval_char->master->in_room == lval_char->in_room );
	case CHK_ISACTIVE:
	    return( lval_char != NULL && lval_char->position > POS_SLEEPING );
	case CHK_ISDELAY:
	    return( lval_char != NULL && lval_char->mprog_delay > 0 );
	case CHK_ISVISIBLE:
            switch( code )
            {
                default :
                case 'i':
                case 'n':
                case 't':
                case 'r':
		case 'q':
	    	    return( lval_char != NULL && can_see( mob, lval_char ) );
		case 'o':
		case 'p':
	    	    return( lval_obj != NULL && can_see_obj( mob, lval_obj ) );
	    }
	case CHK_HASTARGET:
	    return( lval_char != NULL && lval_char->mprog_target != NULL
		&&  lval_char->in_room == lval_char->mprog_target->in_room );
	case CHK_ISTARGET:
	    return( lval_char != NULL && mob->mprog_target == lval_char );
	default:;
     }

     /* 
      * Case 4: Keyword, actor and value
      */
     line = one_argument( line, buf );
     switch( check )
     {
	case CHK_AFFECTED:
	    return( lval_char != NULL 
		&&  IS_SET(lval_char->affected_by, flag_lookup(buf, affect_flags)) );
	case CHK_ACT:
	    return( lval_char != NULL 
		&&  IS_SET(lval_char->act, flag_lookup(buf, act_flags)) );
	case CHK_IMM:
	    return( lval_char != NULL 
		&&  IS_SET(lval_char->imm_flags, flag_lookup(buf, imm_flags)) );
	case CHK_OFF:
	    return( lval_char != NULL 
		&&  IS_SET(lval_char->off_flags, flag_lookup(buf, off_flags)) );
	case CHK_CARRIES:
	    if ( is_number( buf ) )
		return( lval_char != NULL && has_item( lval_char, atoi(buf), -1, FALSE ) );
	    else
		return( lval_char != NULL && (get_obj_carry( lval_char, buf ) != NULL) );
	case CHK_WEARS:
	    if ( is_number( buf ) )
		return( lval_char != NULL && has_item( lval_char, atoi(buf), -1, TRUE ) );
	    else
		return( lval_char != NULL && (get_obj_wear( lval_char, buf ) != NULL) );
	case CHK_HAS:
	    return( lval_char != NULL && has_item( lval_char, -1, item_lookup(buf), FALSE ) );
	case CHK_USES:
	    return( lval_char != NULL && has_item( lval_char, -1, item_lookup(buf), TRUE ) );
	case CHK_NAME:
            switch( code )
            {
                default :
                case 'i':
                case 'n':
                case 't':
                case 'r':
		case 'q':
		    return( lval_char != NULL && is_name( buf, lval_char->name ) );
		case 'o':
		case 'p':
		    return( lval_obj != NULL && is_name( buf, lval_obj->name ) );
	    }
	case CHK_POS:
	    return( lval_char != NULL && lval_char->position == position_lookup( buf ) );
	case CHK_CLAN:
	    return( lval_char != NULL && lval_char->clan == clan_lookup( buf ) );
	case CHK_RACE:
	    return( lval_char != NULL && lval_char->race == race_lookup( buf ) );
	case CHK_OBJTYPE:
	    return( lval_obj != NULL && lval_obj->item_type == item_lookup( buf ) );
	default:;
    }

    /*
     * Case 5: Keyword, actor, comparison and value
     */
    if ( (oper = keyword_lookup( fn_evals, buf )) < 0 )
    {
	sprintf( buf, "Cmd_eval: prog %d syntax error(5): '%s'",
		vnum, original );
	bug( buf, 0 );
	return FALSE;
    }
    one_argument( line, buf );
    rval = atoi( buf );

    switch( check )
    {
	case CHK_VNUM:
	    switch( code )
            {
                default :
                case 'i':
                case 'n':
                case 't':
                case 'r':
		case 'q':
                    if( lval_char != NULL && IS_NPC( lval_char ) )
                        lval = lval_char->pIndexData->vnum;
                    break;
                case 'o':
                case 'p':
                     if ( lval_obj != NULL )
                        lval = lval_obj->pIndexData->vnum;
            }
            break;
	case CHK_HPCNT:
	    if ( lval_char != NULL ) lval = (lval_char->hit * 100)/(UMAX(1,lval_char->max_hit)); break;
	case CHK_ROOM:
	    if ( lval_char != NULL && lval_char->in_room != NULL )
		lval = lval_char->in_room->vnum; break;
        case CHK_SEX:
	    if ( lval_char != NULL ) lval = lval_char->sex; break;
        case CHK_LEVEL:
            if ( lval_char != NULL ) lval = lval_char->level; break;
	case CHK_ALIGN:
            if ( lval_char != NULL ) lval = lval_char->alignment; break;
	case CHK_MONEY:  /* Money is converted to silver... */
	    if ( lval_char != NULL ) 
		lval = lval_char->gold + (lval_char->silver * 100); break;
	case CHK_OBJVAL0:
            if ( lval_obj != NULL ) lval = lval_obj->value[0]; break;
        case CHK_OBJVAL1:
            if ( lval_obj != NULL ) lval = lval_obj->value[1]; break;
        case CHK_OBJVAL2: 
            if ( lval_obj != NULL ) lval = lval_obj->value[2]; break;
        case CHK_OBJVAL3:
            if ( lval_obj != NULL ) lval = lval_obj->value[3]; break;
	case CHK_OBJVAL4:
	    if ( lval_obj != NULL ) lval = lval_obj->value[4]; break;
	case CHK_GRPSIZE:
	    if( lval_char != NULL ) lval = count_people_room( lval_char, 4 ); break;
	default:
            return FALSE;
    }
    return( num_eval( lval, oper, rval ) );
}
Beispiel #4
0
void program_flow( 
        sh_int pvnum,  /* For diagnostic purposes */
	char *source,  /* the actual MOBprog code */
	CHAR_DATA *mob, CHAR_DATA *ch, const void *arg1, const void *arg2 )
{
    CHAR_DATA *rch = NULL;
    char *code, *line;
    char buf[MAX_STRING_LENGTH];
    char control[MAX_INPUT_LENGTH], data[MAX_STRING_LENGTH];

    static int call_level; /* Keep track of nested "mpcall"s */

    int level, eval, check;
    int state[MAX_NESTED_LEVEL], /* Block state (BEGIN,IN,END) */
	cond[MAX_NESTED_LEVEL];  /* Boolean value based on the last if-check */

    sh_int mvnum = mob->pIndexData->vnum;

    if( ++call_level > MAX_CALL_LEVEL )
    {
	bug( "MOBprogs: MAX_CALL_LEVEL exceeded, vnum %d", mob->pIndexData->vnum );
	return;
    }

    /*
     * Reset "stack"
     */
    for ( level = 0; level < MAX_NESTED_LEVEL; level++ )
    {
    	state[level] = IN_BLOCK;
        cond[level]  = TRUE;
    }
    level = 0;

    code = source;
    /*
     * Parse the MOBprog code
     */
    while ( *code )
    {
	bool first_arg = TRUE;
	char *b = buf, *c = control, *d = data;
	/*
	 * Get a command line. We sneakily get both the control word
	 * (if/and/or) and the rest of the line in one pass.
	 */
	while( isspace( *code ) && *code ) code++;
	while ( *code )
	{
	    if ( *code == '\n' || *code == '\r' )
		break;
	    else if ( isspace(*code) )
	    {
		if ( first_arg )
		    first_arg = FALSE;
		else
		    *d++ = *code;
	    }
	    else
	    {
		if ( first_arg )
		   *c++ = *code;
		else
		   *d++ = *code;
	    }
	    *b++ = *code++;
	}
	*b = *c = *d = '\0';

	if ( buf[0] == '\0' )
	    break;
	if ( buf[0] == '*' ) /* Comment */
	    continue;

        line = data;
	/* 
	 * Match control words
	 */
	if ( !str_cmp( control, "if" ) )
	{
	    if ( state[level] == BEGIN_BLOCK )
	    {
		sprintf( buf, "Mobprog: misplaced if statement, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    state[level] = BEGIN_BLOCK;
            if ( ++level >= MAX_NESTED_LEVEL )
            {
		sprintf( buf, "Mobprog: Max nested level exceeded, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    if ( level && cond[level-1] == FALSE ) 
	    {
		cond[level] = FALSE;
		continue;
	    }
	    line = one_argument( line, control );
	    if ( ( check = keyword_lookup( fn_keyword, control ) ) >= 0 )
	    {
		cond[level] = cmd_eval( pvnum, line, check, mob, ch, arg1, arg2, rch );
	    }
	    else
	    {
		sprintf( buf, "Mobprog: invalid if_check (if), mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    state[level] = END_BLOCK;
    	}
	else if ( !str_cmp( control, "or" ) )
	{
	    if ( !level || state[level-1] != BEGIN_BLOCK )
	    {
		sprintf( buf, "Mobprog: or without if, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    if ( level && cond[level-1] == FALSE ) continue;
	    line = one_argument( line, control );
	    if ( ( check = keyword_lookup( fn_keyword, control ) ) >= 0 )
	    {
		eval = cmd_eval( pvnum, line, check, mob, ch, arg1, arg2, rch );
	    }
	    else
            {
		sprintf( buf, "Mobprog: invalid if_check (or), mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
            }
            cond[level] = (eval == TRUE) ? TRUE : cond[level];
    	}
	else if ( !str_cmp( control, "and" ) )
	{
	    if ( !level || state[level-1] != BEGIN_BLOCK )
	    {
		sprintf( buf, "Mobprog: and without if, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    if ( level && cond[level-1] == FALSE ) continue;
	    line = one_argument( line, control );
	    if ( ( check = keyword_lookup( fn_keyword, control ) ) >= 0 )
	    {
		eval = cmd_eval( pvnum, line, check, mob, ch, arg1, arg2, rch );
	    }
	    else
	    {
		sprintf( buf, "Mobprog: invalid if_check (and), mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    cond[level] = (cond[level] == TRUE) && (eval == TRUE) ? TRUE : FALSE;
    	}
	else if ( !str_cmp( control, "endif" ) )
	{
	    if ( !level || state[level-1] != BEGIN_BLOCK )
	    {
		sprintf( buf, "Mobprog: endif without if, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    cond[level] = TRUE;
	    state[level] = IN_BLOCK;
            state[--level] = END_BLOCK;
        }
	else if ( !str_cmp( control, "else" ) )
	{
	    if ( !level || state[level-1] != BEGIN_BLOCK )
	    {
		sprintf( buf, "Mobprog: else without if, mob %d prog %d",
			mvnum, pvnum );
		bug( buf, 0 );
		return;
	    }
	    if ( level && cond[level-1] == FALSE ) continue;
            state[level] = IN_BLOCK;
            cond[level] = (cond[level] == TRUE) ? FALSE : TRUE;
        }
    	else if ( cond[level] == TRUE
	&& ( !str_cmp( control, "break" ) || !str_cmp( control, "end" ) ) )
	{
	    call_level--;
            return;
	}
	else if ( (!level || cond[level] == TRUE) && buf[0] != '\0' )
	{
	    state[level] = IN_BLOCK;
            expand_arg( data, buf, mob, ch, arg1, arg2, rch );
	    if ( !str_cmp( control, "mob" ) )
	    {
		/* 
		 * Found a mob restricted command, pass it to mob interpreter
		 */
		line = one_argument( data, control );
		mob_interpret( mob, line );
	    }
	    else
	    {
		/* 
		 * Found a normal mud command, pass it to interpreter
		 */
		interpret( mob, data );
	    }
	}
    }
    call_level--;
}
Beispiel #5
0
bool adam_keyword_lookup(const name_t& name)
{
    return keyword_lookup(name);
}