示例#1
0
/**
 * @brief	Split the command line into its parts
 * @author	R.Lillback
 * @date	1-Sep-2015
 *
 * @details	This function uses my strings.c FindChar and GetSubString functions.
 *          It splits the command line into 2 components.  The syntax of a command is
 *          COMMAND SUBCOMMAND
 *          where COMMAND 		= Text
 *          and   SUBCOMMAND 	= a Number
 *
 *          the subcommand is returned as an integer result from this function
 *
 * @param   strCommand = pointer to the input buffer
 * @param   strMainCmd = pointer to the main command buffer
 * @param   strSubCmdOne = pointer to the text subcommand buffer
 *
 * @returns the integer value of the sub command, if any.  If none, it returns 0.
 *
 */
int ParseCommands(char* strCommand, char strMainCmd[], char strSubCmdOne[])
{
	int iSpaceOne;				// String location of the first space
	int iEnd;					// String location of the end of the command
	int i;
	int iSubCmdOne;

	iSpaceOne = FindChar(' ', strCommand, 0);	// Find the first space
	iEnd = FindChar('\0', strCommand, 0);		// Get the end of line
	if (iSpaceOne > 0)
	{
		GetSubstring(0, iSpaceOne-1, strCommand, strMainCmd);						// Get main command
		GetSubstring(iSpaceOne+1, iEnd, strCommand, strSubCmdOne);					// Get sub command
		iSubCmdOne = StrToInt(strSubCmdOne);										// Convert sub command to a number
	}
	else // No space, so just have one command
	{
		for (i=0; i<MAX_INPUT_LINE_LEN; i++) strMainCmd[i] =  strCommand[i];		// we just have a single command
		for (i=0; i<MAX_INPUT_LINE_LEN; i++) strSubCmdOne[i] = '\0';				// Sub-command is blank
		iSubCmdOne = 0;
	}

	return iSubCmdOne;

} // ParseCommands
string CFastaIOWrapper::GetRawDefline(unsigned int index) const
{
    if (!m_cacheRawFasta) 
        return "";
    else
        return GetSubstring(m_rawFastaString, index, true);
}
string CFastaIOWrapper::GetActiveSequence(unsigned int index, bool removeWhitespace) const
{
    string s = GetSubstring(m_activeFastaString, index, false);
    if (removeWhitespace) {
        s = RemoveWhitespace_CJL(s);
    }
    return s;
}
wchar_t *ExciteWindow::FindTranslatedText(wchar_t* html)
{
	int slen;
	wchar_t *start = GetSubstring(html, L"name=\"after\"", L"</textarea>", &slen);
	if (!slen)
	{
		start = GetSubstring(html, L"name=after", L"</textarea>", &slen);
		if (!slen)
			return NULL;
	}
	wchar_t *out = wcschr(start, L'>');
	if (!out || out - start >= slen)
		return NULL;
	start[slen] = 0;
	UnescapeHtml(++out, 0);
	return out;
}
SharedUtilsStringType StripDialogEvents(const SharedUtilsStringType &s)
{
    SharedUtilsStringType strippedString = s;

    while (StringIndexOf(strippedString, '{') != StringIndexNotFoundValue() && StringIndexOf(strippedString, '}') != StringIndexNotFoundValue())
    {
        int eventStart = StringIndexOf(strippedString, '{');
        SharedUtilsStringListType eventComponents = split(GetSubstring(strippedString, eventStart + 1, StringIndexOf(strippedString, '}') - eventStart - 1), ':');
        SharedUtilsStringType replacementText = "";
        eventComponents[0] = StringToLower(eventComponents[0]);
        SharedUtilsStringType testString = eventComponents[0];

        if (testString == "fullstop")
        {
            if (eventComponents.size() > 1)
            {
                replacementText = eventComponents[1];
            }
            else
            {
                replacementText = ".";
            }
        }
        else if (testString == "halfstop")
        {
            if (eventComponents.size() > 1)
            {
                replacementText = eventComponents[1];
            }
            else
            {
                replacementText = ",";
            }
        }
        else if (testString == "ellipsis")
        {
            replacementText = "...";
        }

        strippedString = GetSubstring(strippedString, 0, StringIndexOf(strippedString, '{')) + replacementText + GetSubstring(strippedString, StringIndexOf(strippedString, '}') + 1);
    }

    return strippedString;
}
string CFastaIOWrapper::GetRawSequence(unsigned int index, bool removeWhitespace) const
{
    string s = "";
    if (m_cacheRawFasta) {
        s = GetSubstring(m_rawFastaString, index, false);
        if (removeWhitespace) {
            s = RemoveWhitespace_CJL(s);
        }
    }
    return s;
}
wchar_t *BabelfishWindow::FindTranslatedText(wchar_t* html)
{
	int slen;
	wchar_t *start = GetSubstring(html, L"<li class=\"s_after\">", L"</li>", &slen);
	if (!slen)
		return NULL;
	start[slen] = 0;
	if (start[slen - 1] == ')')
	{
		wchar_t *p;
		for (p = start + slen - 2; p > start && (*p | 0x20u) - 'a' <= 'z' - 'a'; p--);
		if (p[0] == '(' && p[-1] == ' ')
			p[-1] = 0;
	}
	UnescapeHtml(start, 0);
	return start;
}
string CFastaIOWrapper::GetActiveDefline(unsigned int index) const
{
    return GetSubstring(m_activeFastaString, index, true);
}
SharedUtilsStringType ParseDialogEvents(IDialogEventsOwner *pDialogEventsOwner, int lineOffset, const SharedUtilsStringType &stringToParse, SharedUtilsStringType *pStringToPrependOnNext)
{
    SharedUtilsStringType parsedString = stringToParse;
    *pStringToPrependOnNext = "";

    while (StringIndexOf(parsedString, '{') != StringIndexNotFoundValue() && StringIndexOf(parsedString, '}') != StringIndexNotFoundValue())
    {
        int eventStart = StringIndexOf(parsedString, '{');
        int eventEnd = StringIndexOf(parsedString, '}');

        SharedUtilsStringListType eventComponents = split(GetSubstring(parsedString, eventStart + 1, eventEnd - eventStart - 1), ':');
        SharedUtilsStringType replacementText = "";
        eventComponents[0] = StringToLower(eventComponents[0]);
        SharedUtilsStringType testString = eventComponents[0];

        if (pDialogEventsOwner != NULL)
        {
            if (testString == "speed")
            {
                double newMillisecondsPerCharacterUpdate = StringToInt(eventComponents[1]);
                pDialogEventsOwner->AddSpeedChangePosition(lineOffset + eventStart, newMillisecondsPerCharacterUpdate);
            }
            else if (testString == "emotion")
            {
                SharedUtilsStringType newEmotion = eventComponents[1];
                pDialogEventsOwner->AddEmotionChangePosition(lineOffset + eventStart, newEmotion);
            }
            else if (testString == "otheremotion")
            {
                SharedUtilsStringType newOtherEmotion = eventComponents[1];
                pDialogEventsOwner->AddEmotionOtherChangePosition(lineOffset + eventStart, newOtherEmotion);
            }
            else if (testString == "pause")
            {
                double millisecondDuration = StringToInt(eventComponents[1]);
                pDialogEventsOwner->AddPausePosition(lineOffset + eventStart, millisecondDuration);
            }
            else if (testString == "audiopause")
            {
                double millisecondDuration = StringToInt(eventComponents[1]);
                pDialogEventsOwner->AddAudioPausePosition(lineOffset + eventStart, millisecondDuration);
             }
            else if (testString == "mouth")
            {
                eventComponents[1] = StringToLower(eventComponents[1]);
                bool mouthIsOn = eventComponents[1] == "on";
                pDialogEventsOwner->AddMouthChangePosition(lineOffset + eventStart, mouthIsOn);
            }
            else if (testString == "fullstop")
            {
                if (eventComponents.size() > 1)
                {
                    replacementText = eventComponents[1];
                }
                else
                {
                    replacementText = ".";
                }

                pDialogEventsOwner->AddMouthChangePosition(lineOffset + eventStart, false /* mouthIsOn */);
                pDialogEventsOwner->AddPausePosition(lineOffset + eventStart + 1, FullStopMillisecondPause);

                if (eventEnd + 1 == (int)parsedString.length())
                {
                    *pStringToPrependOnNext = "{Mouth:On}";
                }
                else
                {
                    pDialogEventsOwner->AddMouthChangePosition(lineOffset + eventStart + 1, true /* mouthIsOn */);
                }
            }
            else if (testString == "halfstop")
            {
                if (eventComponents.size() > 1)
                {
                    replacementText = eventComponents[1];
                }
                else
                {
                    replacementText = ",";
                }

                pDialogEventsOwner->AddMouthChangePosition(lineOffset + eventStart, false /* mouthIsOn */);
                pDialogEventsOwner->AddPausePosition(lineOffset + eventStart + 1, HalfStopMillisecondPause);

                if (eventEnd + 1 == (int)parsedString.length())
                {
                    *pStringToPrependOnNext = "{Mouth:On}";
                }
                else
                {
                    pDialogEventsOwner->AddMouthChangePosition(lineOffset + eventStart + 1, true /* mouthIsOn */);
                }
            }
            else if (testString == "ellipsis")
            {
                replacementText = "...";

                pDialogEventsOwner->AddMouthChangePosition(lineOffset + eventStart, false /* mouthIsOn */);
                pDialogEventsOwner->AddPausePosition(lineOffset + eventStart + 1, EllipsisMillisecondPause);
                pDialogEventsOwner->AddPausePosition(lineOffset + eventStart + 2, EllipsisMillisecondPause);
                pDialogEventsOwner->AddPausePosition(lineOffset + eventStart + 3, EllipsisMillisecondPause);

                if (eventEnd + 1 == (int)parsedString.length())
                {
                    *pStringToPrependOnNext = "{Mouth:On}";
                }
                else
                {
                    pDialogEventsOwner->AddMouthChangePosition(lineOffset + eventStart + 3, true /* mouthIsOn */);
                }
            }
            else if (testString == "aside")
            {
                int currentIndex = lineOffset + eventStart;
                pDialogEventsOwner->StartAside(currentIndex);
            }
            else if (testString == "/aside")
            {
                int currentIndex = lineOffset + eventStart;
                pDialogEventsOwner->EndAside(currentIndex, eventEnd, static_cast<int>(parsedString.length()), pStringToPrependOnNext);
            }
            else if (testString == "emphasis")
            {
                int currentIndex = lineOffset + eventStart;
                pDialogEventsOwner->StartEmphasis(currentIndex);
            }
            else if (testString == "/emphasis")
            {
                int currentIndex = lineOffset + eventStart;
                pDialogEventsOwner->EndEmphasis(currentIndex);
            }
            else if (testString == "playsound")
            {
                SharedUtilsStringType soundId = eventComponents[1];
                pDialogEventsOwner->AddPlaySoundPosition(lineOffset + eventStart, soundId);
            }
            else if (testString == "shake")
            {
                pDialogEventsOwner->AddShakePosition(lineOffset + eventStart);
            }
            else if (testString == "screenshake")
            {
                double shakeIntensity = Min(Max(StringToInt(eventComponents[1]), 0.0), 100.0);
                pDialogEventsOwner->AddScreenShakePosition(lineOffset + eventStart, shakeIntensity);
            }
            else if (testString == "nextframe")
            {
                pDialogEventsOwner->AddNextFramePosition(lineOffset + eventStart);
            }
            else if (testString == "damageplayer")
            {
                pDialogEventsOwner->AddPlayerDamagedPosition(lineOffset + eventStart);
            }
            else if (testString == "damageopponent")
            {
                pDialogEventsOwner->AddOpponentDamagedPosition(lineOffset + eventStart);
            }
            else if (testString == "playbgm")
            {
                SharedUtilsStringType bgmId = eventComponents[1];
                pDialogEventsOwner->AddPlayBgmPosition(lineOffset + eventStart, bgmId);
            }
            else if (testString == "playbgmpermanently")
            {
                SharedUtilsStringType bgmId = eventComponents[1];
                pDialogEventsOwner->AddPlayBgmPermanentlyPosition(lineOffset + eventStart, bgmId);
            }
            else if (testString == "stopbgm")
            {
                pDialogEventsOwner->AddStopBgmPosition(lineOffset + eventStart);
            }
            else if (testString == "stopbgmpermanently")
            {
                pDialogEventsOwner->AddStopBgmPermanentlyPosition(lineOffset + eventStart);
            }
            else if (testString == "stopbgminstantly")
            {
                pDialogEventsOwner->AddStopBgmInstantlyPosition(lineOffset + eventStart);
            }
            else if (testString == "stopbgminstantlypermanently")
            {
                pDialogEventsOwner->AddStopBgmInstantlyPermanentlyPosition(lineOffset + eventStart);
            }
            else if (testString == "zoom")
            {
                pDialogEventsOwner->AddZoomPosition(lineOffset + eventStart);
            }
            else if (testString == "endzoom")
            {
                pDialogEventsOwner->AddEndZoomPosition(lineOffset + eventStart);
            }
            else if (testString == "beginbreakdown")
            {
                pDialogEventsOwner->AddBeginBreakdownPosition(lineOffset + eventStart);
            }
            else if (testString == "endbreakdown")
            {
                pDialogEventsOwner->AddEndBreakdownPosition(lineOffset + eventStart);
            }
            else
            {
                ThrowException("Unknown event.");
            }
        }
        else
        {
            if (testString == "fullstop")
            {
                if (eventComponents.size() > 1)
                {
                    replacementText = eventComponents[1];
                }
                else
                {
                    replacementText = ".";
                }

                if (eventEnd + 1 == (int)parsedString.length())
                {
                    *pStringToPrependOnNext = "{Mouth:On}";
                }
            }
            else if (testString == "halfstop")
            {
                if (eventComponents.size() > 1)
                {
                    replacementText = eventComponents[1];
                }
                else
                {
                    replacementText = ",";
                }

                if (eventEnd + 1 == (int)parsedString.length())
                {
                    *pStringToPrependOnNext = "{Mouth:On}";
                }
            }
            else if (testString == "ellipsis")
            {
                replacementText = "...";

                if (eventEnd + 1 == (int)parsedString.length())
                {
                    *pStringToPrependOnNext = "{Mouth:On}";
                }
            }
            else if (testString == "ellipsis")
            {
                if (eventEnd + 1 == (int)parsedString.length())
                {
                    *pStringToPrependOnNext = "{Mouth:On}";
                }
            }
        }

        parsedString = GetSubstring(parsedString, 0, eventStart) + replacementText + GetSubstring(parsedString, eventEnd + 1);
    }

    return parsedString;
}
SharedUtilsStringType ParseRawDialog(IDialogEventsOwner *pDialogEventsOwner, const SharedUtilsStringType &rawDialog, RectangleWH textAreaRect, double desiredPadding, SharedUtilsFontType dialogFont)
{
    double allowedWidth = textAreaRect.GetWidth() - desiredPadding * 2;
    SharedUtilsStringType fullString = "";
    SharedUtilsStringListType wordList = split(rawDialog, ' ');

    while (!wordList.empty())
    {
        SharedUtilsStringType curstring = "";
        double curTextWidth = 0;
        bool lineDone = false;
        bool addSpace = false;

        if (fullString.length() > 0)
        {
            fullString += "\n";
        }

        while (!lineDone)
        {
            SharedUtilsStringType stringToTest = (addSpace ? " " : "") + wordList.front();
            double curStringWidth = GetStringWidth(StripDialogEvents(stringToTest), dialogFont);

            // If we've got a single word that takes up more than the entire length of the screen,
            // then we need to split it up.
            if (curTextWidth == 0 && curStringWidth > allowedWidth)
            {
                SharedUtilsStringType testString = "";
                SharedUtilsStringType lastTestString = "";
                curStringWidth = 0;

                while (curStringWidth <= allowedWidth)
                {
                    if (stringToTest[0] == '{')
                    {
                        testString += stringToTest[0];
                        stringToTest = GetSubstring(stringToTest, 1);

                        while (stringToTest[0] != '}')
                        {
                            testString += stringToTest[0];
                            stringToTest = GetSubstring(stringToTest, 1);
                        }

                        testString += stringToTest[0];
                        stringToTest = GetSubstring(stringToTest, 1);
                    }

                    lastTestString = testString;
                    testString += stringToTest[0];
                    double testCurStringWidth = GetStringWidth(StripDialogEvents(testString), dialogFont);

                    if (testCurStringWidth > allowedWidth)
                    {
                        break;
                    }

                    curStringWidth = testCurStringWidth;
                    stringToTest = GetSubstring(stringToTest, 1);
                }

                wordList.insert(wordList.begin() + 1, stringToTest);
                stringToTest = lastTestString;
            }

            if (curTextWidth + curStringWidth <= allowedWidth)
            {
                SharedUtilsStringType stringToPrependOnNext;
                stringToTest = ParseDialogEvents(pDialogEventsOwner, static_cast<int>(fullString.length() + curstring.length()), stringToTest, &stringToPrependOnNext);
                curstring += stringToTest;
                curTextWidth += curStringWidth;
                wordList.pop_front();
                addSpace = true;

                if (wordList.empty())
                {
                    lineDone = true;
                }
                else
                {
                    wordList[0] = stringToPrependOnNext + wordList.front();
                }
            }
            else
            {
                lineDone = true;
            }
        }

        fullString += curstring;
    }

    return fullString;
}
示例#11
0
文件: scanner.c 项目: Yghifi/MaoLang
void scan(Trienode* var_map, char* stmt)
{
	char *_temp_id = (char *)malloc(LINE_LENGTH_MAX * sizeof(char));
	char *_type = (char *)malloc(WORD_LENGTH_MAX * sizeof(char));
	void *_value = NULL;
	char *_stmt_o = stmt;
	

	if (IsPrefix(&stmt, "int") || IsPrefix(&stmt, "double"))		
	{
        //variables declaration
		int _tt = 0;
		double _ff = 0.0;

		if (IsPrefix(&_stmt_o, "int"))
		{
			_type = "int";
			_value = &_tt;
		}
		else
		{
			_type = "double";
			_value = &_ff;
		}

		_temp_id = strtok(stmt, ",");
		while (_temp_id != NULL)
		{
			if (!IdCheck(&_temp_id))
			{
				printf("Invalid identifier!\n");
				break;
			}
		  
			AddToTrie(var_map, _temp_id, _type, _value);

			_temp_id = strtok(NULL, ",");
		}
	}
	else if (IsPrefix(&stmt, "print"))
	{
		//print statements

		char* _temp_stmt = (char*)malloc(LINE_LENGTH_MAX * sizeof(char));
		int _pos_i = 0, _pos_j = strlen(stmt);

		while (stmt[_pos_i] != '(')
			_pos_i++;
		while (stmt[_pos_j] != ')')
			_pos_j--;
		if (strchr(stmt, '(') == NULL)
			printf("\"(\" is missing here!\n");
		if (strchr(stmt, ')') == NULL)
			printf("\")\" is missing here!\n");

		_temp_stmt = GetSubstring(stmt, _pos_i + 1, _pos_j - _pos_i - 1);
		//printf("%s\n", _temp_stmt);
	
	
		Expression* _expr = GetAssign(&_temp_stmt);

		GetResult(_expr, var_map);

		PrintExprResult(_expr);

	}
	else
	{
		//normal statements

		Expression* _expr = GetAssign(&stmt);
		
		while (*stmt == ' ' || *stmt == ';')
		{
			stmt++;
		}

		if (strlen(stmt) != 0)
		{
			free(_expr);
			printf("Extra characters!\n");
		}
		else
		{
			GetResult(_expr, var_map);
			/*
			PrintRPN(_expr);
			printf("\n");
			PrintExprResult(_expr);
			*/
		}
	}

	return;
}
示例#12
0
int RegEx::Replace(char *text, size_t textMaxLen, const char *replace, size_t replaceLen, int flags)
{
	char *output = text;

	/**
	 * Retrieve all matches and store them in 
	 * mSubStrings list.
	 */
	if (MatchAll(output) == -1)
	{
		return -1;
	}

	size_t subjectLen = strlen(subject);
	size_t total = 0;
	size_t baseIndex = 0;
	size_t diffLength = 0;

	char *toReplace = new char[textMaxLen + 1];
	char *toSearch = NULL;

	/**
	 * All characters which is not matched are not copied when replacing matches.
	 * Then original text (output buffer) should be considerated as empty.
	 */
	if (flags & REGEX_FORMAT_NOCOPY)
	{
		*output = '\0';
	}
	else
	{
		/**
		 * This is used only when we do replace matches.
		 */
		toSearch  = new char[textMaxLen + 1];
	}

	/** 
	 * Loop over all matches found.
	 */
	for (size_t i = 0; i < mMatchesSubs.length(); ++i)
	{
		char *ptr = toReplace;

		size_t browsed = 0;
		size_t searchLen = 0;
		size_t length = 0;
	
		/**
		 * Build the replace string as it can contain backreference
		 * and this needs to be parsed.
		 */
		for (const char *s = replace, *end = s + replaceLen; s < end && browsed <= textMaxLen; ++s, ++browsed)
		{
			unsigned int c = *s;

			/**
			 * Supported format specifiers:
			 *
			 *   $number  : Substitutes the substring matched by group number.
			 *              n must be an integer value designating a valid backreference, greater than 0, and of two digits at most.
			 *   ${name}  : Substitutes the substring matched by the named group name (a maximum of 32 characters).
			 *   $&       : Substitutes a copy of the whole match.
			 *   $`       : Substitutes all the text of the input string before the match.
			 *   $'       : Substitutes all the text of the input string after the match.
			 *   $+       : Substitutes the last group that was captured.
			 *   $_       : Substitutes the entire input string.
			 *   $$       : Substitutes a literal "$".
			 */
			if (c == '$' || c == '\\')
			{
				switch (*++s)
				{
					case '\0':
					{
						/**
						 * End of string.
						 * Copy one character.
						 */
						 *(ptr + browsed) = c;
						 break;
					}
					case '&':
					{
						/**
						 * Concatenate retrieved full match sub-string.
						 * length - 1 to overwrite EOS.
						 */
						GetSubstring(baseIndex, ptr + browsed, textMaxLen, &length);
						browsed += length - 1;
						break;
					}
					case '`':
					{
						/**
						 * Concatenate part of original text up to
						 * first sub-string position.
						 */
						length = mSubStrings.at(baseIndex).start;
						memcpy(ptr + browsed, subject, length);
						browsed += length - 1;
						break;
					}
					case '\'':
					{
						/**
						 * Concatenate part of original text from
						 * last sub-string end position to EOS.
						 */
						length = mSubStrings.at(baseIndex).end;
						memcpy(ptr + browsed, subject + length, subjectLen - length);
						browsed += (subjectLen - length) - 1;
						break;
					}
					case '+':
					{
						/**
						 * Copy the last group that was captured.
						 */
						GetSubstring(baseIndex + mMatchesSubs.at(i) - 1, ptr + browsed, textMaxLen, &length);
						browsed += length - 1;
						break;
					}
					case '_':
					{
						/**
						 * Copy the entire input string.
						 */
						memcpy(ptr + browsed, subject, subjectLen);
						browsed += (subjectLen - 1);
						break;
					}
					case '$':
					case '\\':
					{
						/**
						 * Copy the single character $ or \.
						 */
						*(ptr + browsed) = c;
						break;
					}
					case '0': case '1':	case '2': case '3':	case '4': 
					case '5': case '6': case '7': case '8': case '9':
					case '{':
					{
						/**
						 * Checking backreference.
						 * Which can be either $n, ${n} or ${name}.
						 */
						int backref = -1;
						const char *walk = s;
						bool inBrace = false;
						bool nameCheck = false;

						/**
						 * ${nn}.
						 *  ^
						 */
						if (*walk == '{') 
						{
							inBrace = true;
							++walk;
						}

						/**
						 * Valid number.
						 * $nn or ${nn}
						 *  ^       ^
						 */
						if (*walk >= '0' && *walk <= '9')
						{
							backref = *walk - '0';
							++walk;
						}
						else if (inBrace)
						{
							nameCheck = true;

							/**
							 * Not a valid number.
							 * Checking as string.
							 * ${name}
							 *   ^
							 */
							if (*walk)
							{
								const char *pch = strchr(walk, '}');

								if (pch != NULL)
								{
									/**
									 * A named group maximum character is 32 (PCRE).
									 */
									char name[32];
									size_t nameLength = strncopy(name, walk, pch - walk + 1);

									int flags, num = 0;
									pcre_fullinfo(re, NULL, PCRE_INFO_OPTIONS, &flags);

									/**
									 * If PCRE_DUPNAMES is set, the pcre_copy_named_substring function should be used
									 * as pcre_get_stringnumber output order is not defined.
									 */
									if (flags & PCRE_DUPNAMES)
									{
										memset(ovector, 0, REGEX_MAX_SUBPATTERNS);

										/**
										 * pcre_copy_named_substring needs a vector containing sub-patterns ranges
										 * for a given match.
										 */
										for (size_t j = 0; j < mMatchesSubs.at(i); ++j)
										{
											ovector[2 * j] = mSubStrings.at(baseIndex + j).start;
											ovector[2 * j + 1] = mSubStrings.at(baseIndex + j).end;
										}

										num = pcre_copy_named_substring(re, subject, ovector, mMatchesSubs.at(i), name, ptr + browsed, (int)textMaxLen);

										if (num != PCRE_ERROR_NOSUBSTRING)
										{
											browsed += num - 1;
											s = pch;
											break;
										}
										++pch;
									}
									else
									{
										/**
										 * Retrieve sub-pattern index from a give name.
										 */
										num = pcre_get_stringnumber(re, name);
										if (num != PCRE_ERROR_NOSUBSTRING)
										{
											backref = num;
											walk = ++pch;
										}
									}

									if (num == PCRE_ERROR_NOSUBSTRING || num >= (int)mMatchesSubs.at(i))
									{
										/**
										 * If a sub-string for a given match is not found,  or if > to
										 * number of sub-patterns we still need to check if this 
										 * group name is a valid one because if so we want to escape it. 
										 * Looking at the name table.
										 */
										bool found = false;
										for (size_t i = 0; i < mSubsNameTable.length(); ++i)
										{
											if (!mSubsNameTable.at(i).name.compare(name))
											{
												--browsed;
												s = --pch;
												found = true;
												break;
											}
										}

										if (found)
										{
											continue;
										}
									}
								}
							}
						}

						if (!nameCheck)
						{
							/**
							 * Valid second number.
							 * $nn or ${nn}
							 *   ^       ^
							 */
							if (*walk && *walk >= '0' && *walk <= '9')
							{
								backref = backref * 10 + *walk - '0';
								++walk;
							}

							if (inBrace)
							{
								/**
								 * Invalid specifier
								 * Either hit EOS or missing }.
								 * ${n  or ${nn  or ${nx or ${nnx
								 *    ^        ^       ^        ^
								 */
								if (*walk == '\0' || *walk != '}')
								{
									backref = -1;
								}
								else
								{
									++walk;
								}
							}
						}

						length = walk - s;
						s = --walk;

						/**
						 * We can't provide a capture number >= to total that pcre_exec has found.
						 * 0 is implicitly accepted, same behavior as $&.
						 */
						if (backref >= 0 && backref < mNumSubpatterns)
						{
							/**
							 * Valid available index for a given match.
							 */
							if ((size_t)backref < mMatchesSubs.at(i))
							{
								/**
								 * Concatenate retrieved sub-string.
								 * length - 1 to overwrite EOS.
								 */
								GetSubstring(baseIndex + backref, ptr + browsed, textMaxLen, &length);
								browsed += length - 1;
							}
							else
							{
								/**
								 * Valid unavailable index for a given match.
								 */
								--browsed;
							}
						}
						else
						{
							/**
							 * If we here it means the syntax is valid but sub-pattern doesn't exist. 
							 * So, copy as it is, including $.
							 */
							memcpy(ptr + browsed, s - length, length + 1);
							browsed += length;
						}

						break;
					}
					default:
					{
						/**
						 * Not a valid format modifier.
						 * So we copy characters as it is.
						 */
						*(ptr + browsed) = *s;
						break;
					}
				}
			}
			else
			{
				/**
				 * At this point, direct copy.
				 */
				*(ptr + browsed) = c;
			}
		}

		*(ptr + browsed) = '\0';

		/**
		 * Concatenate only replace string of each match, 
		 * as we don't want to copy unmatched characters.
		 */
		if (flags & REGEX_FORMAT_NOCOPY)
		{
			/**
			 * We want just the first occurrence.
			 */
			if (total++ && (flags & REGEX_FORMAT_FIRSTONLY))
			{
				break;
			}

			strncat(output, toReplace, textMaxLen + 1);
		}
		else
		{
			/**
			 * Retrieves full string of a given match.
			 */
			const char *search = GetSubstring(baseIndex, toSearch, textMaxLen, &searchLen);

			/**
			 * We get something to replace, but the sub-pattern to search is empty.
			 * We insert replacement either a the start end or string.
			 */
			if (*toReplace && !searchLen)
			{
				if (output - text > 0)
				{
					strncat(output, toReplace, textMaxLen);
				}
				else
				{
					strncat(toReplace, text, textMaxLen);
					strncopy(text, toReplace, strlen(toReplace) + 1);
				}

				++total;
			}
			else if ((output = UTIL_ReplaceEx(text + mSubStrings.at(baseIndex).start + diffLength, textMaxLen, search, searchLen, toReplace, browsed, false)) != NULL)
			{
				/**
				 * Then we simply do a replace.
				 * Probably not the most efficient, but this should be at least safe.
				 * To avoid issue where the function could find a string which is not at the expected index,
				 * We force the input string to start from index of the full match.
				 */
				++total;
			}

			if (total && (flags & REGEX_FORMAT_FIRSTONLY))
			{
				break;
			}
		}

		/**
		 * mMatchesSubs is a flat list containing all sub-patterns of all matches.
		 * A number of sub-patterns can vary per match. So we calculate the position in the list, 
		 * from where the first sub-pattern result of current match starts.
		 */
		baseIndex  += mMatchesSubs.at(i);
		diffLength += browsed - searchLen;
	}

	delete[] toReplace;
	
	if (toSearch != NULL)
	{
		delete[] toSearch;
	}

	/**
	 * Return the number of successful replacements.
	 */
	return total;
}
示例#13
0
CString CTreeListItem::GetSubstring(CTreeListCtrl& treeListCtrl,HTREEITEM item,int nSub) const
{
   return GetSubstring(nSub);
}