Exemple #1
0
   bool run(String string,int pos,int len)
   {
      #ifdef HX_SMART_STRINGS
      if (string.isUTF16Encoded())
      {
         if (!rUtf16)
         {
            const char *error = 0;
            int err_offset = 0;
            hx::strbuf buf;
            rUtf16 = pcre16_compile((PCRE_SPTR16)expr.wc_str(&buf),flags|PCRE_UTF16,&error,&err_offset,NULL);
            if (!rUtf16)
            {
               return false;
            }
         }

         int n =  pcre16_exec(rUtf16,NULL,(const unsigned short *)string.raw_wptr(),pos+len,pos,0,matchs,nmatchs * 3);
         return n>=0;
      }

      if (!rUtf8)
      {
         rUtf8 =  pcre_compile(expr.utf8_str(),flags|PCRE_UTF8,0,0,0);
         if (!rUtf8)
            return false;
      }

      #endif
      return pcre_exec(rUtf8,NULL,string.utf8_str(),pos+len,pos,0,matchs,nmatchs * 3) >= 0;
   }
Exemple #2
0
int regcomp(regex_t *preg, MCStringRef pattern, int cflags)
{
	const char *errorptr;
	int erroffset;
	int options = 0;

	if ((cflags & REG_ICASE) != 0)
		options |= PCRE_CASELESS;
    if ((cflags & REG_NEWLINE) != 0)
		options |= PCRE_MULTILINE;

    // AL-2014-08-20: [[ Bug 13186 ]] Ensure pattern string doesn't get permanently converted to UTF-16
    MCAutoStringRef t_temp;
    /* UNCHECKED */ MCStringMutableCopy(pattern, &t_temp);
    
    // SN-2014-01-14: [[ libpcre update ]]
    preg->re_pcre = pcre16_compile((PCRE_SPTR16)MCStringGetCharPtr(*t_temp), options, &errorptr, &erroffset, NULL);
	preg->re_erroffset = erroffset;

	if (preg->re_pcre == NULL)
		return eint[erroffset];

//    [[ libpcre udpate ]] SN-2014-01-10: pcre_info() is deprecated, must be replaced with pcre_fullinfo()
    return pcre16_fullinfo((const pcre16 *)preg->re_pcre, NULL, PCRE_INFO_CAPTURECOUNT, &preg->re_nsub);
}
Exemple #3
0
Dynamic _hx_regexp_new_options(String s, String opt)
{
   hx::strbuf buf;
   const char *o = opt.utf8_str(&buf);
   int options = PCRE_UCP;
   while( *o )
   {
      switch( *o++ )
      {
      case 'i':
         options |= PCRE_CASELESS;
         break;
      case 's':
         options |= PCRE_DOTALL;
         break;
      case 'm':
         options |= PCRE_MULTILINE;
         break;
      case 'g':
         options |= PCRE_UNGREEDY;
         break;
      case 'u':
         break;
      default:
         hx::Throw( HX_CSTRING("Regexp unknown modifier : ") + String::fromCharCode(o[-1]) );
         break;
      }
   }

   #ifdef HX_SMART_STRINGS
   if (s.isUTF16Encoded())
   {
      const char *error = 0;
      int err_offset = 0;
      pcre16 *p =  pcre16_compile((PCRE_SPTR16)s.raw_wptr(),options|PCRE_UTF16,&error,&err_offset,NULL);
      if( !p )
         hx::Throw( HX_CSTRING("Regexp compilation error : ")+String(error)+HX_CSTRING(" in ")+s);

      pcredata *pdata = new pcredata;
      pdata->create16(p,s,options);
      return pdata;
   }
   else
   #endif
   {
      const char *error = 0;
      int err_offset = 0;

      pcre *p =  pcre_compile(s.utf8_str(),options|PCRE_UTF8,&error,&err_offset,NULL);
      if( !p )
         hx::Throw( HX_CSTRING("Regexp compilation error : ")+String(error)+HX_CSTRING(" in ")+s);

      pcredata *pdata = new pcredata;
      pdata->create8(p,s,options);
      return pdata;
   }
}
Exemple #4
0
static const unsigned char *tables(int mode)
{
	/* The purpose of this function to allow valgrind
	for reporting invalid reads and writes. */
	static unsigned char *tables_copy;
	const char *errorptr;
	int erroroffset;
	const unsigned char *default_tables;
#ifdef SUPPORT_PCRE8
	pcre *regex;
	char null_str[1] = { 0 };
#else
	pcre16 *regex;
	PCRE_UCHAR16 null_str[1] = { 0 };
#endif

	if (mode) {
		if (tables_copy)
			free(tables_copy);
		tables_copy = NULL;
		return NULL;
	}

	if (tables_copy)
		return tables_copy;

	default_tables = NULL;
#ifdef SUPPORT_PCRE8
	regex = pcre_compile(null_str, 0, &errorptr, &erroroffset, NULL);
	if (regex) {
		pcre_fullinfo(regex, NULL, PCRE_INFO_DEFAULT_TABLES, &default_tables);
		pcre_free(regex);
	}
#else
	regex = pcre16_compile(null_str, 0, &errorptr, &erroroffset, NULL);
	if (regex) {
		pcre16_fullinfo(regex, NULL, PCRE_INFO_DEFAULT_TABLES, &default_tables);
		pcre16_free(regex);
	}
#endif
	/* Shouldn't ever happen. */
	if (!default_tables)
		return NULL;

	/* Unfortunately this value cannot get from pcre_fullinfo.
	Since this is a test program, this is acceptable at the moment. */
	tables_copy = (unsigned char *)malloc(1088);
	if (!tables_copy)
		return NULL;

	memcpy(tables_copy, default_tables, 1088);
	return tables_copy;
}
Exemple #5
0
static ejsval
_ejs_RegExp_impl (ejsval env, ejsval _this, uint32_t argc, ejsval *args)
{
    EJSRegExp *re;

    if (EJSVAL_IS_UNDEFINED(_this)) {
        // called as a function
        _this = _ejs_object_new(_ejs_RegExp_prototype, &_ejs_RegExp_specops);
    }

    re = (EJSRegExp*)EJSVAL_TO_OBJECT(_this);

    re->pattern = _ejs_undefined;
    re->flags = _ejs_undefined;

    if (argc > 0) re->pattern = args[0];
    if (argc > 1) re->flags = args[1];

    if (!EJSVAL_IS_STRING(re->pattern))
        EJS_NOT_IMPLEMENTED();

    EJSPrimString *flat_pattern = _ejs_string_flatten (re->pattern);
    jschar* chars = flat_pattern->data.flat;

    const unsigned char* pcre16_tables = pcre16_maketables();
    const char *pcre_error;
    int pcre_erroffset;

    re->compiled_pattern = pcre16_compile(chars,
                                          PCRE_UTF16 | PCRE_NO_UTF16_CHECK,
                                          &pcre_error, &pcre_erroffset,
                                          pcre16_tables);

    _ejs_object_define_value_property (_this, _ejs_atom_source, re->pattern, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE | EJS_PROP_NOT_WRITABLE);

    if (EJSVAL_IS_STRING(re->flags)) {
        EJSPrimString *flat_flags = _ejs_string_flatten(re->flags);
        chars = flat_flags->data.flat;

        for (int i = 0; i < flat_flags->length; i ++) {
            if      (chars[i] == 'g' && !re->global)     { re->global     = EJS_TRUE; continue; }
            else if (chars[i] == 'i' && !re->ignoreCase) { re->ignoreCase = EJS_TRUE; continue; }
            else if (chars[i] == 'm' && !re->multiline)  { re->multiline  = EJS_TRUE; continue; }
            else if (chars[i] == 'y' && !re->sticky)     { re->sticky     = EJS_TRUE; continue; }
            else if (chars[i] == 'u' && !re->unicode)    { re->unicode    = EJS_TRUE; continue; }
            _ejs_throw_nativeerror_utf8 (EJS_SYNTAX_ERROR, "Invalid flag supplied to RegExp constructor");
        }
    }

    return _this;
}
Exemple #6
0
RegExp* RegExp::create(const U16String& pattern, unsigned int flags) {
    RegExp* re = new RegExp(pattern, flags);
    int error = 0;

#ifdef LIBJ_USE_PCRE16
    const char* errstr;
    int fs = (flags & IGNORE_CASE ? PCRE_CASELESS : 0)
           | (flags & MULTILINE ? PCRE_MULTILINE : 0);
    re->code_ = pcre16_compile(pattern.c_str(), fs, &errstr, &error, NULL);
#else
    iv::core::Space space;
    int fs = (flags & IGNORE_CASE ? iv::aero::IGNORE_CASE : 0)
           | (flags & MULTILINE ? iv::aero::MULTILINE : 0);
    re->code_ = iv::aero::Compile(&space, pattern, fs, &error);
#endif

    if (!error && re->code_) {
        return re;
    } else {
        delete re;
        return NULL;
    }
}
Exemple #7
0
/*
** Substitutes part of the text
*/
const WCHAR* Measure::CheckSubstitute(const WCHAR* buffer)
{
	static std::wstring str;

	if (m_Substitute.empty())
	{
		return buffer;
	}

	str = buffer;
	if (!m_RegExpSubstitute)
	{
		for (size_t i = 0, isize = m_Substitute.size(); i < isize; i += 2)
		{
			if (!m_Substitute[i].empty())
			{
				MakePlainSubstitute(str, i);
			}
			else if (str.empty())
			{
				// Empty result and empty substitute -> use second
				str = m_Substitute[i + 1];
			}
		}
	}
	else
	{
		int ovector[300];
		for (size_t i = 0, isize = m_Substitute.size(); i < isize; i += 2)
		{
			const char* error;
			int errorOffset;
			int offset = 0;
			pcre16* re = pcre16_compile(
				(PCRE_SPTR16)m_Substitute[i].c_str(),
				PCRE_UTF16,
				&error,
				&errorOffset,
				nullptr);  // Use default character tables.
			if (!re)
			{
				MakePlainSubstitute(str, i);
				LogNoticeF(this, L"Substitute: %S", error);
			}
			else
			{
				do
				{
					const int options = str.empty() ? 0 : PCRE_NOTEMPTY;
					const int rc = pcre16_exec(
						re,
						nullptr,
						(PCRE_SPTR16)str.c_str(),
						(int)str.length(),
						offset,
						options,               // Empty string is not a valid match
						ovector,
						(int)_countof(ovector));
					if (rc <= 0)
					{
						break;
					}

					std::wstring result = m_Substitute[i + 1];

					if (rc > 1)
					{
						for (int j = rc - 1 ; j >= 0 ; --j)
						{
							int newStart = ovector[2 * j];
							size_t inLength = ovector[2 * j + 1] - ovector[2 * j];

							if (newStart < 0) break;	// Match was not found, so skip to the next item

							WCHAR tmpName[64];
							size_t cutLength = _snwprintf_s(tmpName, _TRUNCATE, L"\\%i", j);
							size_t start = 0, pos;
							do
							{
								pos = result.find(tmpName, start, cutLength);
								if (pos != std::string::npos)
								{
									result.replace(pos, cutLength, str, (size_t)newStart, inLength);
									start = pos + inLength;
								}
							}
							while (pos != std::string::npos);
						}
					}

					const int start = ovector[0];
					const int length = ovector[1] - ovector[0];
					str.replace(start, length, result);
					offset = start + (int)result.length();
				}
				while (true);

				pcre16_free(re);
			}
		}
	}

	return str.c_str();
}
Exemple #8
0
TCString CompileRegexp(TCString Regexp, int bAddAsUsualSubstring, int ID)
{
	TCString Result(_T(""));
	sPcreCompileData s = {0};
	int NewID = PcreCompileData.AddElem(s);
	PcreCompileData[NewID].ID = ID;
	if (!bAddAsUsualSubstring)
	{
		const char *Err;
		int ErrOffs;
		int Flags = PCRE_CASELESS;
		if (Regexp[0] == '/')
		{
			TCString OrigRegexp = Regexp;
			Regexp = Regexp.Right(Regexp.GetLen() - 1);
			TCHAR *pRegexpEnd = (TCHAR*)Regexp + Regexp.GetLen();
			TCHAR *p = _tcsrchr(Regexp.GetBuffer(), '/');
			if (!p)
			{
				Regexp = OrigRegexp;
			} else
			{
				*p = 0;
				Flags = 0;
				while (++p < pRegexpEnd)
				{
					switch (*p) {
					case 'i':
						Flags |= PCRE_CASELESS;
						break;
					case 'm':
						Flags |= PCRE_MULTILINE;
						break;
					case 's':
						Flags |= PCRE_DOTALL;
						break;
					case 'x':
						Flags |= PCRE_EXTENDED;
						break;
					case 'A':
						Flags |= PCRE_ANCHORED;
						break;
					case 'f':
						Flags |= PCRE_FIRSTLINE;
						break;
					case 'D':
						Flags |= PCRE_DOLLAR_ENDONLY;
						break;
					case 'U':
						Flags |= PCRE_UNGREEDY;
						break;
					case 'X':
						Flags |= PCRE_EXTRA;
						break;
					default:
						// Result += LogMessage(Translate("Warning, unknown pattern modifier '%c':\n"), *p );
						break;
					}
				}
			}
			Regexp.ReleaseBuffer();
		}

		PcreCompileData[NewID].pPcre = pcre16_compile(Regexp, PCRE_UTF8 | PCRE_NO_UTF8_CHECK | Flags, &Err, &ErrOffs, NULL);

		if (PcreCompileData[NewID].pPcre) {
			PcreCompileData[NewID].pExtra = NULL;
			PcreCompileData[NewID].pExtra = pcre16_study(PcreCompileData[NewID].pPcre, 0, &Err);
		} 
		else {
			// Result += LogMessage(TranslateT("Syntax error in regexp\n%s\nat offset %d: %s."), (TCHAR*)Regexp, ErrOffs, (TCHAR*)ANSI2TCHAR(Err)) + _T("\n\n");
			PcreCompileData[NewID].Pattern = Regexp;
	 	}
	} 
	else PcreCompileData[NewID].Pattern = Regexp;

	return Result;
}
Exemple #9
0
static int regression_tests(void)
{
	struct regression_test_case *current = regression_test_cases;
	const char *error;
	const char *cpu_info;
	int i, err_offs;
	int is_successful, is_ascii_pattern, is_ascii_input;
	int total = 0;
	int successful = 0;
	int counter = 0;
#ifdef SUPPORT_PCRE8
	pcre *re8;
	pcre_extra *extra8;
	int ovector8_1[32];
	int ovector8_2[32];
	int return_value8_1, return_value8_2;
	int utf8 = 0, ucp8 = 0;
	int disabled_flags8 = 0;
#endif
#ifdef SUPPORT_PCRE16
	pcre16 *re16;
	pcre16_extra *extra16;
	int ovector16_1[32];
	int ovector16_2[32];
	int return_value16_1, return_value16_2;
	int utf16 = 0, ucp16 = 0;
	int disabled_flags16 = 0;
	int length16;
#endif

	/* This test compares the behaviour of interpreter and JIT. Although disabling
	utf or ucp may make tests fail, if the pcre_exec result is the SAME, it is
	still considered successful from pcre_jit_test point of view. */

#ifdef SUPPORT_PCRE8
	pcre_config(PCRE_CONFIG_JITTARGET, &cpu_info);
#else
	pcre16_config(PCRE_CONFIG_JITTARGET, &cpu_info);
#endif

	printf("Running JIT regression tests\n");
	printf("  target CPU of SLJIT compiler: %s\n", cpu_info);

#ifdef SUPPORT_PCRE8
	pcre_config(PCRE_CONFIG_UTF8, &utf8);
	pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp8);
	if (!utf8)
		disabled_flags8 |= PCRE_UTF8;
	if (!ucp8)
		disabled_flags8 |= PCRE_UCP;
	printf("  in  8 bit mode with utf8  %s and ucp %s:\n", utf8 ? "enabled" : "disabled", ucp8 ? "enabled" : "disabled");
#endif
#ifdef SUPPORT_PCRE16
	pcre16_config(PCRE_CONFIG_UTF16, &utf16);
	pcre16_config(PCRE_CONFIG_UNICODE_PROPERTIES, &ucp16);
	if (!utf16)
		disabled_flags16 |= PCRE_UTF8;
	if (!ucp16)
		disabled_flags16 |= PCRE_UCP;
	printf("  in 16 bit mode with utf16 %s and ucp %s:\n", utf16 ? "enabled" : "disabled", ucp16 ? "enabled" : "disabled");
#endif

	while (current->pattern) {
		/* printf("\nPattern: %s :\n", current->pattern); */
		total++;
		if (current->start_offset & F_PROPERTY) {
			is_ascii_pattern = 0;
			is_ascii_input = 0;
		} else {
			is_ascii_pattern = check_ascii(current->pattern);
			is_ascii_input = check_ascii(current->input);
		}

		error = NULL;
#ifdef SUPPORT_PCRE8
		re8 = NULL;
		if (!(current->start_offset & F_NO8))
			re8 = pcre_compile(current->pattern,
				current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | disabled_flags8),
				&error, &err_offs, tables(0));

		extra8 = NULL;
		if (re8) {
			error = NULL;
			extra8 = pcre_study(re8, PCRE_STUDY_JIT_COMPILE, &error);
			if (!extra8) {
				printf("\n8 bit: Cannot study pattern: %s\n", current->pattern);
				pcre_free(re8);
				re8 = NULL;
			}
			if (!(extra8->flags & PCRE_EXTRA_EXECUTABLE_JIT)) {
				printf("\n8 bit: JIT compiler does not support: %s\n", current->pattern);
				pcre_free_study(extra8);
				pcre_free(re8);
				re8 = NULL;
			}
		} else if (((utf8 && ucp8) || is_ascii_pattern) && !(current->start_offset & F_NO8))
			printf("\n8 bit: Cannot compile pattern: %s\n", current->pattern);
#endif
#ifdef SUPPORT_PCRE16
		if ((current->flags & PCRE_UTF8) || (current->start_offset & F_FORCECONV))
			convert_utf8_to_utf16(current->pattern, regtest_buf, NULL, REGTEST_MAX_LENGTH);
		else
			copy_char8_to_char16(current->pattern, regtest_buf, REGTEST_MAX_LENGTH);

		re16 = NULL;
		if (!(current->start_offset & F_NO16))
			re16 = pcre16_compile(regtest_buf,
				current->flags & ~(PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | disabled_flags16),
				&error, &err_offs, tables(0));

		extra16 = NULL;
		if (re16) {
			error = NULL;
			extra16 = pcre16_study(re16, PCRE_STUDY_JIT_COMPILE, &error);
			if (!extra16) {
				printf("\n16 bit: Cannot study pattern: %s\n", current->pattern);
				pcre16_free(re16);
				re16 = NULL;
			}
			if (!(extra16->flags & PCRE_EXTRA_EXECUTABLE_JIT)) {
				printf("\n16 bit: JIT compiler does not support: %s\n", current->pattern);
				pcre16_free_study(extra16);
				pcre16_free(re16);
				re16 = NULL;
			}
		} else if (((utf16 && ucp16) || is_ascii_pattern) && !(current->start_offset & F_NO16))
			printf("\n16 bit: Cannot compile pattern: %s\n", current->pattern);
#endif

		counter++;
		if ((counter & 0x3) != 0) {
#ifdef SUPPORT_PCRE8
			setstack8(NULL);
#endif
#ifdef SUPPORT_PCRE16
			setstack16(NULL);
#endif
		}

#ifdef SUPPORT_PCRE8
		return_value8_1 = -1000;
		return_value8_2 = -1000;
		for (i = 0; i < 32; ++i)
			ovector8_1[i] = -2;
		for (i = 0; i < 32; ++i)
			ovector8_2[i] = -2;
		if (re8) {
			setstack8(extra8);
			return_value8_1 = pcre_exec(re8, extra8, current->input, strlen(current->input), current->start_offset & OFFSET_MASK,
				current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART), ovector8_1, 32);
			return_value8_2 = pcre_exec(re8, NULL, current->input, strlen(current->input), current->start_offset & OFFSET_MASK,
				current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART), ovector8_2, 32);
		}
#endif

#ifdef SUPPORT_PCRE16
		return_value16_1 = -1000;
		return_value16_2 = -1000;
		for (i = 0; i < 32; ++i)
			ovector16_1[i] = -2;
		for (i = 0; i < 32; ++i)
			ovector16_2[i] = -2;
		if (re16) {
			setstack16(extra16);
			if ((current->flags & PCRE_UTF8) || (current->start_offset & F_FORCECONV))
				length16 = convert_utf8_to_utf16(current->input, regtest_buf, regtest_offsetmap, REGTEST_MAX_LENGTH);
			else
				length16 = copy_char8_to_char16(current->input, regtest_buf, REGTEST_MAX_LENGTH);
			return_value16_1 = pcre16_exec(re16, extra16, regtest_buf, length16, current->start_offset & OFFSET_MASK,
				current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART), ovector16_1, 32);
			return_value16_2 = pcre16_exec(re16, NULL, regtest_buf, length16, current->start_offset & OFFSET_MASK,
				current->flags & (PCRE_NOTBOL | PCRE_NOTEOL | PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART), ovector16_2, 32);
		}
#endif

		/* If F_DIFF is set, just run the test, but do not compare the results.
		Segfaults can still be captured. */

		is_successful = 1;
		if (!(current->start_offset & F_DIFF)) {
#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
			if (utf8 == utf16 && !(current->start_offset & F_FORCECONV)) {
				/* All results must be the same. */
				if (return_value8_1 != return_value8_2 || return_value8_1 != return_value16_1 || return_value8_1 != return_value16_2) {
					printf("\n8 and 16 bit: Return value differs(%d:%d:%d:%d): [%d] '%s' @ '%s'\n",
						return_value8_1, return_value8_2, return_value16_1, return_value16_2,
						total, current->pattern, current->input);
					is_successful = 0;
				} else if (return_value8_1 >= 0) {
					return_value8_1 *= 2;
					/* Transform back the results. */
					if (current->flags & PCRE_UTF8) {
						for (i = 0; i < return_value8_1; ++i) {
							if (ovector16_1[i] >= 0)
								ovector16_1[i] = regtest_offsetmap[ovector16_1[i]];
							if (ovector16_2[i] >= 0)
								ovector16_2[i] = regtest_offsetmap[ovector16_2[i]];
						}
					}

					for (i = 0; i < return_value8_1; ++i)
						if (ovector8_1[i] != ovector8_2[i] || ovector8_1[i] != ovector16_1[i] || ovector8_1[i] != ovector16_2[i]) {
							printf("\n8 and 16 bit: Ovector[%d] value differs(%d:%d:%d:%d): [%d] '%s' @ '%s' \n",
								i, ovector8_1[i], ovector8_2[i], ovector16_1[i], ovector16_2[i],
								total, current->pattern, current->input);
							is_successful = 0;
						}
				}
			} else {
#endif /* SUPPORT_PCRE8 && SUPPORT_PCRE16 */
				/* Only the 8 bit and 16 bit results must be equal. */
#ifdef SUPPORT_PCRE8
				if (return_value8_1 != return_value8_2) {
					printf("\n8 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n",
						return_value8_1, return_value8_2, total, current->pattern, current->input);
					is_successful = 0;
				} else if (return_value8_1 >= 0) {
					return_value8_1 *= 2;
					for (i = 0; i < return_value8_1; ++i)
						if (ovector8_1[i] != ovector8_2[i]) {
							printf("\n8 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n",
								i, ovector8_1[i], ovector8_2[i], total, current->pattern, current->input);
							is_successful = 0;
						}
				}
#endif

#ifdef SUPPORT_PCRE16
				if (return_value16_1 != return_value16_2) {
					printf("\n16 bit: Return value differs(%d:%d): [%d] '%s' @ '%s'\n",
						return_value16_1, return_value16_2, total, current->pattern, current->input);
					is_successful = 0;
				} else if (return_value16_1 >= 0) {
					return_value16_1 *= 2;
					for (i = 0; i < return_value16_1; ++i)
						if (ovector16_1[i] != ovector16_2[i]) {
							printf("\n16 bit: Ovector[%d] value differs(%d:%d): [%d] '%s' @ '%s'\n",
								i, ovector16_1[i], ovector16_2[i], total, current->pattern, current->input);
							is_successful = 0;
						}
				}
#endif

#if defined SUPPORT_PCRE8 && defined SUPPORT_PCRE16
			}
#endif /* SUPPORT_PCRE8 && SUPPORT_PCRE16 */
		}

		if (is_successful) {
#ifdef SUPPORT_PCRE8
			if (!(current->start_offset & F_NO8) && ((utf8 && ucp8) || is_ascii_input)) {
				if (return_value8_1 < 0 && !(current->start_offset & F_NOMATCH)) {
					printf("8 bit: Test should match: [%d] '%s' @ '%s'\n",
						total, current->pattern, current->input);
					is_successful = 0;
				}

				if (return_value8_1 >= 0 && (current->start_offset & F_NOMATCH)) {
					printf("8 bit: Test should not match: [%d] '%s' @ '%s'\n",
						total, current->pattern, current->input);
					is_successful = 0;
				}
			}
#endif
#ifdef SUPPORT_PCRE16
			if (!(current->start_offset & F_NO16) && ((utf16 && ucp16) || is_ascii_input)) {
				if (return_value16_1 < 0 && !(current->start_offset & F_NOMATCH)) {
					printf("16 bit: Test should match: [%d] '%s' @ '%s'\n",
						total, current->pattern, current->input);
					is_successful = 0;
				}

				if (return_value16_1 >= 0 && (current->start_offset & F_NOMATCH)) {
					printf("16 bit: Test should not match: [%d] '%s' @ '%s'\n",
						total, current->pattern, current->input);
					is_successful = 0;
				}
			}
#endif
		}

		if (is_successful)
			successful++;

#ifdef SUPPORT_PCRE8
		if (re8) {
			pcre_free_study(extra8);
			pcre_free(re8);
		}
#endif
#ifdef SUPPORT_PCRE16
		if (re16) {
			pcre16_free_study(extra16);
			pcre16_free(re16);
		}
#endif

		/* printf("[%d-%d|%d-%d]%s", ovector8_1[0], ovector8_1[1], ovector16_1[0], ovector16_1[1], (current->flags & PCRE_CASELESS) ? "C" : ""); */
		printf(".");
		fflush(stdout);
		current++;
	}
	tables(1);
#ifdef SUPPORT_PCRE8
	setstack8(NULL);
#endif
#ifdef SUPPORT_PCRE16
	setstack16(NULL);
#endif

	if (total == successful) {
		printf("\nAll JIT regression tests are successfully passed.\n");
		return 0;
	} else {
		printf("\nSuccessful test ratio: %d%% (%d failed)\n", successful * 100 / total, total - successful);
		return 1;
	}
}
Exemple #10
0
void IfActions::DoIfActions(Measure& measure, double value)
{
	// IfEqual
	if (!m_EqualAction.empty())
	{
		if ((int64_t)value == m_EqualValue)
		{
			if (!m_EqualCommitted)
			{
				m_EqualCommitted = true;		// To avoid infinite loop from !Update
				GetRainmeter().ExecuteCommand(m_EqualAction.c_str(), measure.GetSkin());
			}
		}
		else
		{
			m_EqualCommitted = false;
		}
	}

	// IfAbove
	if (!m_AboveAction.empty())
	{
		if (value > m_AboveValue)
		{
			if (!m_AboveCommitted)
			{
				m_AboveCommitted = true;		// To avoid infinite loop from !Update
				GetRainmeter().ExecuteCommand(m_AboveAction.c_str(), measure.GetSkin());
			}
		}
		else
		{
			m_AboveCommitted = false;
		}
	}

	// IfBelow
	if (!m_BelowAction.empty())
	{
		if (value < m_BelowValue)
		{
			if (!m_BelowCommitted)
			{
				m_BelowCommitted = true;		// To avoid infinite loop from !Update
				GetRainmeter().ExecuteCommand(m_BelowAction.c_str(), measure.GetSkin());
			}
		}
		else
		{
			m_BelowCommitted = false;
		}
	}

	// IfCondition
	int i = 0;
	for (auto& item : m_Conditions)
	{
		++i;
		if (!item.value.empty() && (!item.tAction.empty() || !item.fAction.empty()))
		{
			double result = 0.0;
			const WCHAR* errMsg = MathParser::Parse(
				item.value.c_str(), &result, measure.GetCurrentMeasureValue, &measure);
			if (errMsg != nullptr)
			{
				if (!item.parseError)
				{
					if (i == 1)
					{
						LogErrorF(&measure, L"%s: IfCondition=%s", errMsg, item.value.c_str());
					}
					else
					{
						LogErrorF(&measure, L"%s: IfCondition%i=%s", errMsg, i, item.value.c_str());
					}
					item.parseError = true;
				}
			}
			else
			{
				item.parseError = false;

				if (result == 1.0)			// "True"
				{
					item.fCommitted = false;

					if (m_ConditionMode || !item.tCommitted)
					{
						item.tCommitted = true;
						GetRainmeter().ExecuteCommand(item.tAction.c_str(), measure.GetSkin());
					}
				}
				else if (result == 0.0)	// "False"
				{
					item.tCommitted = false;

					if (m_ConditionMode || !item.fCommitted)
					{
						item.fCommitted = true;
						GetRainmeter().ExecuteCommand(item.fAction.c_str(), measure.GetSkin());
					}
				}
			}
		}
	}
	
	// IfMatch
	i = 0;
	for (auto& item : m_Matches)
	{
		++i;
		if (!item.value.empty() && (!item.tAction.empty() || !item.fAction.empty()))
		{
			const char* error;
			int errorOffset;

			pcre16* re = pcre16_compile(
				(PCRE_SPTR16)item.value.c_str(),
				PCRE_UTF16,
				&error,
				&errorOffset,
				nullptr);

			if (!re)
			{
				if (!item.parseError)
				{
					if (i == 1)
					{
						LogErrorF(&measure, L"Error: \"%S\" in IfMatch=%s", error, item.value.c_str());
					}
					else
					{
						LogErrorF(&measure, L"Error: \"%S\" in IfMatch%i=%s", error, i, item.value.c_str());
					}

					item.parseError = true;
				}
			}
			else
			{
				item.parseError = false;

				const WCHAR* str = measure.GetStringValue();
				int strLen = str ? (int)wcslen(str) : 0;
				int ovector[300];
				int rc = pcre16_exec(
					re,
					nullptr,
					(PCRE_SPTR16)str,
					(int)strLen,
					0,
					0,
					ovector,
					(int)_countof(ovector));

				if (rc > 0)		// Match
				{
					item.fCommitted = false;

					if (m_MatchMode || !item.tCommitted)
					{
						item.tCommitted = true;
						GetRainmeter().ExecuteCommand(item.tAction.c_str(), measure.GetSkin());
					}
				}
				else			// Not Match
				{
					item.tCommitted = false;

					if (m_MatchMode || !item.fCommitted)
					{
						item.fCommitted = true;
						GetRainmeter().ExecuteCommand(item.fAction.c_str(), measure.GetSkin());
					}
				}
			}

			// Release memory used for the compiled pattern
			pcre16_free(re);
		}
	}
}
Exemple #11
0
void ParseData(MeasureData* measure, const BYTE* rawData, DWORD rawSize, bool utf16Data)
{
	const int UTF16_CODEPAGE = 1200;
	if (measure->codepage == UTF16_CODEPAGE) {
		utf16Data = true;
	}

	const char* error;
	int erroffset;
	int ovector[OVECCOUNT];
	int rc;
	bool doErrorAction = false;

	// Compile the regular expression in the first argument
	pcre16* re = pcre16_compile(
		(PCRE_SPTR16)measure->regExp.c_str(),
		PCRE_UTF16, &error, &erroffset, nullptr);
	if (re != nullptr)
	{
		// Compilation succeeded: match the subject in the second argument
		std::wstring buffer;
		auto data = (const WCHAR*)rawData;
		DWORD dataLength = rawSize / 2;
		if (!utf16Data)
		{
			buffer = StringUtil::Widen((LPCSTR)rawData, rawSize, measure->codepage);
			data = buffer.c_str();
			dataLength = (DWORD)buffer.length();
		}

		rc = pcre16_exec(re, nullptr, (PCRE_SPTR16)data, dataLength, 0, 0, ovector, OVECCOUNT);
		if (rc >= 0)
		{
			if (rc == 0)
			{
				// The output vector wasn't big enough
				RmLog(measure->rm, LOG_ERROR, L"WebParser: Too many substrings");
			}
			else
			{
				if (measure->stringIndex < rc)
				{
					if (measure->debug != 0)
					{
						for (int i = 0; i < rc; ++i)
						{
							const WCHAR* match = data + ovector[2 * i];
							const int matchLen = min(ovector[2 * i + 1] - ovector[2 * i], 256);
							RmLogF(measure->rm, LOG_DEBUG, L"WebParser: Index %2d: %.*s", i, matchLen, match);
						}
					}

					const WCHAR* match = data + ovector[2 * measure->stringIndex];
					int matchLen = ovector[2 * measure->stringIndex + 1] - ovector[2 * measure->stringIndex];
					EnterCriticalSection(&g_CriticalSection);
					measure->resultString.assign(match, matchLen);
					DecodeReferences(measure->resultString, measure->decodeCharacterReference);
					LeaveCriticalSection(&g_CriticalSection);
				}
				else
				{
					RmLog(measure->rm, LOG_WARNING, L"WebParser: Not enough substrings");

					// Clear the old result
					EnterCriticalSection(&g_CriticalSection);
					measure->resultString.clear();
					if (measure->download)
					{
						if (measure->downloadFile.empty())  // cache mode
						{
							if (!measure->downloadedFile.empty())
							{
								// Delete old downloaded file
								DeleteFile(measure->downloadedFile.c_str());
							}
						}
						measure->downloadedFile.clear();
					}
					LeaveCriticalSection(&g_CriticalSection);
				}

				// Update the references
				std::vector<MeasureData*>::iterator i = g_Measures.begin();
				std::wstring compareStr = L"[";
				compareStr += RmGetMeasureName(measure->rm);
				compareStr += L']';
				for ( ; i != g_Measures.end(); ++i)
				{
					if (measure->skin == (*i)->skin &&
						StringUtil::CaseInsensitiveFind((*i)->url, compareStr) != std::wstring::npos)
					{
						if ((*i)->stringIndex < rc)
						{
							const WCHAR* match = data + ovector[2 * (*i)->stringIndex];
							int matchLen = ovector[2 * (*i)->stringIndex + 1] - ovector[2 * (*i)->stringIndex];
							if (!(*i)->regExp.empty())
							{
								// Change the index and parse the substring
								int index = (*i)->stringIndex;
								(*i)->stringIndex = (*i)->stringIndex2;
								ParseData((*i), (BYTE*)match, matchLen * 2, true);
								(*i)->stringIndex = index;
							}
							else
							{
								// Set the result
								EnterCriticalSection(&g_CriticalSection);

								// Substitude the [measure] with result
								(*i)->resultString = (*i)->url;
								(*i)->resultString.replace(
									StringUtil::CaseInsensitiveFind((*i)->resultString, compareStr),
									compareStr.size(), match, matchLen);
								DecodeReferences((*i)->resultString, (*i)->decodeCharacterReference);

								// Start download threads for the references
								if ((*i)->download)
								{
									// Start the download thread
									unsigned int id;
									HANDLE threadHandle = (HANDLE)_beginthreadex(nullptr, 0, NetworkDownloadThreadProc, (*i), 0, &id);
									if (threadHandle)
									{
										(*i)->dlThreadHandle = threadHandle;
									}
								}

								LeaveCriticalSection(&g_CriticalSection);
							}
						}
						else
						{
							RmLog((*i)->rm, LOG_WARNING, L"WebParser: Not enough substrings");

							// Clear the old result
							EnterCriticalSection(&g_CriticalSection);
							(*i)->resultString.clear();
							if ((*i)->download)
							{
								if ((*i)->downloadFile.empty())  // cache mode
								{
									if (!(*i)->downloadedFile.empty())
									{
										// Delete old downloaded file
										DeleteFile((*i)->downloadedFile.c_str());
									}
								}
								(*i)->downloadedFile.clear();
							}
							LeaveCriticalSection(&g_CriticalSection);
						}
					}
				}
			}
		}
		else
		{
			// Matching failed: handle error cases
			RmLogF(measure->rm, LOG_ERROR, L"WebParser: RegExp matching error (%d)", rc);
			doErrorAction = true;

			EnterCriticalSection(&g_CriticalSection);
			measure->resultString = measure->errorString;

			// Update the references
			std::vector<MeasureData*>::iterator i = g_Measures.begin();
			std::wstring compareStr = L"[";
			compareStr += RmGetMeasureName(measure->rm);
			compareStr += L']';
			for ( ; i != g_Measures.end(); ++i)
			{
				if ((StringUtil::CaseInsensitiveFind((*i)->url, compareStr) != std::wstring::npos) &&
					(measure->skin == (*i)->skin))
				{
					(*i)->resultString = (*i)->errorString;
				}
			}
			LeaveCriticalSection(&g_CriticalSection);
		}

		// Release memory used for the compiled pattern
		pcre16_free(re);
	}
	else
	{
		// Compilation failed.
		RmLogF(measure->rm, LOG_ERROR, L"WebParser: RegExp error at offset %d: %S", erroffset, error);
		doErrorAction = true;
	}

	if (measure->download)
	{
		// Start the download thread
		unsigned int id;
		HANDLE threadHandle = (HANDLE)_beginthreadex(nullptr, 0, NetworkDownloadThreadProc, measure, 0, &id);
		if (threadHandle)
		{
			measure->dlThreadHandle = threadHandle;
		}
	}

	if (doErrorAction && !measure->onRegExpErrAction.empty())
	{
		RmExecute(measure->skin, measure->onRegExpErrAction.c_str());
	}
	else if (!measure->download && !measure->finishAction.empty())
	{
		RmExecute(measure->skin, measure->finishAction.c_str());
	}
}