Example #1
0
File: words.c Project: jnbek/TekNap
/*
 * extract is a simpler version of extract2, it is used when we dont
 * want special treatment of "firstword" if it is negative.  This is
 * typically used by the word/list functions, which also dont care if
 * we strip out or leave in any whitespace, we just do what is the
 * fastest.
 */
char *	real_extract (char *start, int firstword, int lastword, int extended)
{
	/* 
	 * firstword and lastword must be zero.  If they are not,
	 * then they are assumed to be invalid  However, please note
	 * that taking word set (-1,3) is valid and contains the
	 * words 0, 1, 2, 3.  But word set (-1, -1) is an empty_string.
	 */
	char *	mark;
	char *	mark2;
	char *	booya = NULL;

	CHECK_EXTENDED_SUPPORT
	/* 
	 * Before we do anything, we strip off leading and trailing
	 * spaces. 
	 *
	 * ITS OK TO TAKE OUT SPACES HERE, AS THE USER SHOULDNT EXPECT
	 * THAT THE WORD FUNCTIONS WOULD RETAIN ANY SPACES. (That is
	 * to say that since the word/list functions dont pay attention
	 * to the whitespace anyhow, noone should have any problem with
	 * those ops removing bothersome whitespace when needed.)
	 */
	while (my_isspace(*start))
		start++;
	remove_trailing_spaces(start);

	if (firstword == EOS)
	{
		mark = start + strlen(start);
		mark = (char *)move_word_rel(start, (const char **)&mark, -1, extended);
	}

	/* If the firstword is positive, move to that word */
	else if (firstword >= 0)
		real_move_to_abs_word(start, (const char **)&mark, firstword, extended);

	/* Its negative.  Hold off right now. */
	else
		mark = start;


	/* 
	 * When we find the last word, we need to move to the 
         * END of the word, so that word 3 to 3, would include
	 * all of word 3, so we sindex to the space after the word
 	 */
	/* EOS is a #define meaning "end of string" */
	if (lastword == EOS)
		mark2 = start + strlen(start);
	else 
	{
		if (lastword >= 0)
			real_move_to_abs_word(start, (const char **)&mark2, lastword+1, extended);
		else
			/* its negative -- thats not valid */
			return m_strdup(empty_string);

		while (mark2 > start && my_isspace(mark2[-1]))
			mark2--;
	}

	/*
	 * Ok.. now if we get to here, then lastword is positive, so
	 * we sanity check firstword.
	 */
	if (firstword < 0)
		firstword = 0;
	if (firstword > lastword)	/* this works even if fw was < 0 */
		return m_strdup(empty_string);

	/* 
	 * If the end is before the string, then there is nothing
	 * to extract (this is perfectly legal, btw)
         */
	if (mark2 < mark)
		return m_strdup(empty_string);

	booya = strext(mark, mark2);
	return booya;
}
Example #2
0
/*
 * extract2 is the word extractor that is used when its important to us
 * that 'firstword' get special treatment if it is negative (specifically,
 * that it refer to the "firstword"th word from the END).  This is used
 * basically by the ${n}{-m} expandos and by function_rightw(). 
 */
char *	real_extract2 (const char *start, int firstword, int lastword, int extended)
{
	const char *	mark;
	const char *	mark2;
	char *		retval;

	/*
	 * 'firstword == EOS' means we should return the last word
	 * This is used for $~.  Handle the whole shebang here.
	 */
	if (firstword == EOS)
	{
		/* Mark to the end of the string... */
		mark = start + strlen(start);

		/* And move to the start of that word */
		move_word_rel(start, &mark, -1, extended, "\"");

		return malloc_strdup(mark);
	}

	/*
	 * 'firstword == SOS' means the user did $-<num>.
	 * The start of retval is start of string.
	 */
	else if (firstword == SOS)
		mark = start;

	/*
	 * 'firstword is not negative' means user wants to start at
	 * the <firstword>th word.  Move the mark to that position.
	 *
	 * If the mark does not exist (ie, $10- when there are not
	 * 10 words), fail by returning the empty string.
	 */
	else if (firstword >= 0)
	{
		real_move_to_abs_word(start, &mark, firstword, extended, "\"");
		if (!*mark)
			return malloc_strdup(empty_string);
	}

	/*
	 * 'firstword is negative' means user wants to start at the
	 * <firstword>th word from the end.  Move the mark to that
	 * position.  This is used for $rightw() and stuff.
	 */
	else
	{
		mark = start + strlen(start);
		move_word_rel(start, &mark, firstword, extended, "\"");
	}

	/*****************************************************************/
	/*
	 * So now 'mark' points at the start of the string we want to
	 * return; this should include the spaces that lead up to the word.  
	 *
	 * Now we need to find the end of the string to return.
	 */

	/* 
	 * 'lastword is EOS' means the user did $<num>-, so cheat by 
	 * just returning the mark
	 */
	if (lastword == EOS)
	    return malloc_strdup(mark);

	/*
	 * 'lastword is nonnegative' means the user did $<num1>-<num2>,
	 * so we need to move to the start of the <num2 + 1> and go back
	 * one position -- easy, eh?
	 */
	else if (lastword >= 0)
	    real_move_to_abs_word(start, &mark2, lastword + 1, extended, "\"");

	/*
	 * 'lastword is negative' means the user wants all but the last
 	 * <num> words, so we move to the start of the <num>th word from 
	 * the end, and go back one character!
	 */
	else
	{
	    mark2 = start + strlen(start);
	    move_word_rel(start, &mark2, lastword, extended, "\"");
	}

	/*
	 * move back one position, because we are the start of the NEXT word.
	 */
	if (*mark2 && mark2 > start)
		mark2--;

	/* 
	 * If the end is before the string, then there is nothing
	 * to extract (this is perfectly legal, btw)
         */
	if (mark2 < mark)
		return malloc_strdup(empty_string);

	/*
	 * XXX Backwards compatability requires that $<num> not 
	 * have any leading spaces.
	 */
	if (firstword == lastword)
	{
		while (mark && *mark && isspace(*mark))
			mark++;
	}

	/*
	 * This is kind of tricky, because the string we are
	 * copying out of is const.  So we cant just null off
	 * the trailing character and malloc_strdup it.
	 */
	retval = strext(mark, mark2);

	/* 
	 * XXX Backwards compatability requires that $<num> not have
	 * any trailing spaces, even if it is the last word.
	 */
	if (firstword == lastword)
		remove_trailing_spaces(retval, 0);

	return retval;
}
Example #3
0
File: words.c Project: jnbek/TekNap
/*
 * extract2 is the word extractor that is used when its important to us
 * that 'firstword' get special treatment if it is negative (specifically,
 * that it refer to the "firstword"th word from the END).  This is used
 * basically by the ${n}{-m} expandos and by function_rightw(). 
 *
 * Note that because of a lot of flak, if you do an expando that is
 * a "range" of words, unless you #define STRIP_EXTRANEOUS_SPACES,
 * the "n"th word will be backed up to the first character after the
 * first space after the "n-1"th word.  That apparantly is what everyone
 * wants, so thats whatll be the default.  Those of us who may not like
 * that behavior or are at ambivelent can just #define it.
 */
char *	real_extract2 (const char *start, int firstword, int lastword, int extended)
{
	/* 
	 * If firstword or lastword is negative, then
	 * we take those values from the end of the string
	 */
	const char *	mark;
	const char *	mark2;
	char *		booya = NULL;

	CHECK_EXTENDED_SUPPORT
	/* If firstword is EOS, then the user wants the last word */
	if (firstword == EOS)
	{
		mark = start + strlen(start);
		mark = move_word_rel(start, &mark, -1, extended);
#ifndef NO_CHEATING
		/* 
		 * Really. the only case where firstword == EOS is
		 * when the user wants $~, in which case we really
		 * dont need to do all the following crud.  Of
		 * course, if there ever comes a time that the
		 * user would want to start from the EOS (when?)
		 * we couldnt make this assumption.
		 */
		return m_strdup(mark);
#endif
	}

	/* 
	 * SOS is used when the user does $-n, all leading spaces 
	 * are retained  
	 */
	else if (firstword == SOS)
		mark = start;

	/* If the firstword is positive, move to that word */
	/* Special treatment for $X-, where X is out of range
	 * added by Colten Edwards, fixes the $1- bug.. */
	else if (firstword >= 0)
	{
		real_move_to_abs_word(start, &mark, firstword, extended);
		if (!*mark)
			return m_strdup(empty_string);
	}

	/* Otherwise, move to the firstwords from the end */
	else
	{
		mark = start + strlen(start);
		move_word_rel(start, &mark, firstword, extended);
	}

#ifndef STRIP_EXTRANEOUS_SPACES
	/* IF the user did something like this:
	 *	$n-  $n-m
	 * then include any leading spaces on the 'n'th word.
	 * this is the "old" behavior that we are attempting
	 * to emulate here.
	 */
#ifndef NO_CHEATING
	if (lastword == EOS || (lastword > firstword))
#else
	if (((lastword == EOS) && (firstword != EOS)) || (lastword > firstword))
#endif
	{
		while (mark > start && my_isspace(mark[-1]))
			mark--;
		if (mark > start)
			mark++;
	}
#endif

	/* 
	 * When we find the last word, we need to move to the 
         * END of the word, so that word 3 to 3, would include
	 * all of word 3, so we sindex to the space after the word
	 */
	if (lastword == EOS)
		mark2 = mark + strlen(mark);

	else 
	{
		if (lastword >= 0)
			real_move_to_abs_word(start, &mark2, lastword+1, extended);
		else
		{
			mark2 = start + strlen(start);
			move_word_rel(start, &mark2, lastword, extended);
		}

		while (mark2 > start && my_isspace(mark2[-1]))
			mark2--;
	}

	/* 
	 * If the end is before the string, then there is nothing
	 * to extract (this is perfectly legal, btw)
         */
	if (mark2 < mark)
		booya = m_strdup(empty_string);

	else
	{
		/*
		 * This is kind of tricky, because the string we are
		 * copying out of is const.  So we cant just null off
		 * the trailing character and m_strdup it.
		 */
		booya = strext(mark, mark2);
	}

	return booya;
}
Example #4
0
extern char	*BX_extract2(const char *start, int firstword, int lastword)
{
	/* If firstword or lastword is negative, then
	   we take those values from the end of the string */
	char *mark;
	char *mark2;
	char *booya = NULL;

	/* If firstword is EOS, then the user wants the last word */
	if (firstword == EOS)
	{
		mark = (char *)start + strlen(start);
		mark = move_word_rel(start, &mark, -1);
#ifndef NO_CHEATING
		/* 
		 * Really. the only case where firstword == EOS is
		 * when the user wants $~, in which case we really
		 * dont need to do all the following crud.  Of
		 * course, if there ever comes a time that the
		 * user would want to start from the EOS (when??)
		 * we couldnt make this assumption.
		 */
		return m_strdup(mark);
#endif
	}

	/* SOS is used when the user does $-n, all leading spaces 
	 * are retained  
	 */
	else if (firstword == SOS)
		mark = (char *)start;

	/* If the firstword is positive, move to that word */
	else if (firstword >= 0)
	{
		move_to_abs_word(start, &mark, firstword);
		if (!*mark)
			return m_strdup(empty_string);
	}
	/* Otherwise, move to the firstwords from the end */
	else
	{
		mark = (char *)start + strlen((char *)start);
		move_word_rel(start, &mark, firstword);
	}

#ifndef STRIP_EXTRANEOUS_SPACES
	/* IF the user did something like this:
	 *	$n-  $n-m
	 * then include any leading spaces on the 'n'th word.
	 * this is the "old" behavior that we are attempting
	 * to emulate here.
	 */
#ifndef NO_CHEATING
	if (lastword == EOS || (lastword > firstword))
#else
	if (((lastword == EOS) && (firstword != EOS)) || (lastword > firstword))
#endif
	{
		while (mark > start && my_isspace(mark[-1]))
			mark--;
		if (mark > start)
			mark++;
	}
#endif

	/* 
	 * When we find the last word, we need to move to the 
         * END of the word, so that word 3 to 3, would include
	 * all of word 3, so we sindex to the space after the word
	 */
	if (lastword == EOS)
		mark2 = mark + strlen(mark);

	else 
	{
		if (lastword >= 0)
			move_to_abs_word(start, &mark2, lastword+1);
		else
		{
			mark2 = (char *)start + strlen(start);
			move_word_rel(start, &mark2, lastword);
		}

		while (mark2 > start && my_isspace(mark2[-1]))
			mark2--;
	}

	/* 
	 * If the end is before the string, then there is nothing
	 * to extract (this is perfectly legal, btw)
         */
	if (mark2 < mark)
		booya = m_strdup(empty_string);

	else
	{
#if 0
		/* Otherwise, copy off the string we just isolated */ 
		char tmp;
		tmp = *mark2;
		*mark2 = '\0';
		booya = m_strdup(mark);
		*mark2 = tmp;
#endif
		booya = new_malloc(mark2 - mark + 1);
		strmcpy(booya, mark, (mark2 - mark));
	}

	return booya;
}