FreeBSD/contrib/mdocml/mansearch.c
/*
 * Compile a set of string tokens into an expression.
 * Tokens in "argv" are assumed to be individual expression atoms (e.g.,
 * "(", "foo=bar", etc.).
 */
Compile a set of string tokens into an expression.
Tokens in "argv" are assumed to be individual expression atoms .
Compile a set of string tokens into an expression . Tokens in " argv " are assumed to be individual expression atoms .
static struct expr *
exprcomp(const struct mansearch *search, int argc, char *argv[])
{
	uint64_t	 mask;
	int		 i, toopen, logic, igncase, toclose;
	struct expr	*first, *prev, *cur, *next;
	first = cur = NULL;
	logic = igncase = toopen = toclose = 0;
	for (i = 0; i < argc; i++) {
		if (0 == strcmp("(", argv[i])) {
			if (igncase)
				goto fail;
			toopen++;
			toclose++;
			continue;
		} else if (0 == strcmp(")", argv[i])) {
			if (toopen || logic || igncase || NULL == cur)
				goto fail;
			cur->close++;
			if (0 > --toclose)
				goto fail;
			continue;
		} else if (0 == strcmp("-a", argv[i])) {
			if (toopen || logic || igncase || NULL == cur)
				goto fail;
			logic = 1;
			continue;
		} else if (0 == strcmp("-o", argv[i])) {
			if (toopen || logic || igncase || NULL == cur)
				goto fail;
			logic = 2;
			continue;
		} else if (0 == strcmp("-i", argv[i])) {
			if (igncase)
				goto fail;
			igncase = 1;
			continue;
		}
		next = exprterm(search, argv[i], !igncase);
		if (NULL == next)
			goto fail;
		if (NULL == first)
			first = next;
		else
			cur->next = next;
		prev = cur = next;
		for (mask = TYPE_Nm; mask <= TYPE_Nd; mask <<= 1) {
			if (mask & cur->bits && ~mask & cur->bits) {
				next = mandoc_calloc(1,
				    sizeof(struct expr));
				memcpy(next, cur, sizeof(struct expr));
				prev->open = 1;
				cur->bits = mask;
				cur->next = next;
				cur = next;
				cur->bits &= ~mask;
			}
		}
		prev->and = (1 == logic);
		prev->open += toopen;
		if (cur != prev)
			cur->close = 1;
		toopen = logic = igncase = 0;
	}
	if ( ! (toopen || logic || igncase || toclose))
		return first;
fail:
	if (NULL != first)
		exprfree(first);
	return NULL;
}
static struct expr * exprcomp ( const struct mansearch * search , int argc , char * argv [ ] ) { uint64_t mask ; int i , toopen , logic , igncase , toclose ; struct expr * first , * prev , * cur , * next ; first = cur = NULL ; logic = igncase = toopen = toclose = 0 ; for ( i = 0 ; i < argc ; i ++ ) { if ( 0 == strcmp ( " " , argv [ i ] ) ) { if ( igncase ) goto fail ; toopen ++ ; toclose ++ ; continue ; } else if ( 0 == strcmp ( " " , argv [ i ] ) ) { if ( toopen || logic || igncase || NULL == cur ) goto fail ; cur -> close ++ ; if ( 0 > -- toclose ) goto fail ; continue ; } else if ( 0 == strcmp ( " " , argv [ i ] ) ) { if ( toopen || logic || igncase || NULL == cur ) goto fail ; logic = 1 ; continue ; } else if ( 0 == strcmp ( " " , argv [ i ] ) ) { if ( toopen || logic || igncase || NULL == cur ) goto fail ; logic = 2 ; continue ; } else if ( 0 == strcmp ( " " , argv [ i ] ) ) { if ( igncase ) goto fail ; igncase = 1 ; continue ; } next = exprterm ( search , argv [ i ] , ! igncase ) ; if ( NULL == next ) goto fail ; if ( NULL == first ) first = next ; else cur -> next = next ; prev = cur = next ; for ( mask = TYPE_Nm ; mask <= TYPE_Nd ; mask <<= 1 ) { if ( mask & cur -> bits && ~ mask & cur -> bits ) { next = mandoc_calloc ( 1 , sizeof ( struct expr ) ) ; memcpy ( next , cur , sizeof ( struct expr ) ) ; prev -> open = 1 ; cur -> bits = mask ; cur -> next = next ; cur = next ; cur -> bits &= ~ mask ; } } prev -> and = ( 1 == logic ) ; prev -> open += toopen ; if ( cur != prev ) cur -> close = 1 ; toopen = logic = igncase = 0 ; } if ( ! ( toopen || logic || igncase || toclose ) ) return first ; fail : if ( NULL != first ) exprfree ( first ) ; return NULL ; }
Compile a set of string tokens into an expression.
Compile a set of string tokens into an expression .
/*
		 * Searching for descriptions must be split out
		 * because they are stored in the mpages table,
		 * not in the keys table.
		 */