/* Function: iSrchFilterProcessTerm() Purpose: This function processes the passed term, stripping the field name (if present), setting the field ID bit map if needed and stemming the term Parameters: pssSrchSearch search structure psiSrchIndex index structure pvLngStemmer stemmer pwcTerm term pucFieldIDBitmap field ID bitmap (optional) uiFieldIDBitmapLength field ID bitmap length (optional) ppwcTerm return pointer for the processed term pbFieldIDBitmapSet return flag set to true if the field ID bitmap was set Globals: none Returns: SRCH error code */ static int iSrchFilterProcessTerm ( struct srchSearch *pssSrchSearch, struct srchIndex *psiSrchIndex, void *pvLngStemmer, wchar_t *pwcTerm, unsigned char *pucFieldIDBitmap, unsigned int uiFieldIDBitmapLength, wchar_t **ppwcTerm, boolean *pbFieldIDBitmapSet ) { int iError = SRCH_NoError; unsigned char pucFieldName[SRCH_INFO_SYMBOL_MAXIMUM_LENGTH + 1] = {'\0'}; unsigned int uiFieldID = 0; unsigned int uiFieldOptions = SRCH_INFO_FIELD_OPTION_NONE; boolean bFieldIDBitmapSet = false; boolean bContainsUpperCase = false; wchar_t *pwcPtr = NULL; ASSERT(pssSrchSearch != NULL); ASSERT(psiSrchIndex != NULL); ASSERT(pvLngStemmer != NULL); ASSERT(bUtlStringsIsStringNULL(pwcTerm) == false); ASSERT(((pucFieldIDBitmap == NULL) && (uiFieldIDBitmapLength <= 0)) || ((pucFieldIDBitmap != NULL) && (uiFieldIDBitmapLength > 0))); ASSERT(ppwcTerm != NULL); ASSERT(pbFieldIDBitmapSet != NULL); /* Set the field option defaults */ iSrchInfoGetFieldOptionDefaults(psiSrchIndex, &uiFieldOptions); /* Extract field name if present */ if ( (bUtlStringsIsWideStringUrl(pwcTerm) == false) && ((pwcPtr = s_wcspbrk(pwcTerm, SRCH_FILTER_FIELD_NAME_SEPARATORS)) != NULL) ) { wchar_t *pwcFieldNamePtr = NULL; /* Set the field name */ pwcFieldNamePtr = pwcTerm; /* Set the term */ pwcTerm = pwcPtr + 1; /* Null terminate the field name, separating the term from the field name */ *pwcPtr = L'\0'; /* Convert the field name from wide characters to utf-8 */ if ( (iError = iLngConvertWideStringToUtf8_s(pwcFieldNamePtr, 0, pucFieldName, SRCH_INFO_SYMBOL_MAXIMUM_LENGTH + 1)) != LNG_NoError ) { iUtlLogError(UTL_LOG_CONTEXT, "Failed to convert a field name from wide characters to utf-8, lng error: %d.", iError); return (SRCH_FilterCharacterSetConvertionFailed); } /* Look up the field ID for this field */ if ( (iError = iSrchInfoGetFieldID(psiSrchIndex, pucFieldName, &uiFieldID)) == SRCH_NoError ) { /* Get the field options, reset them to the default if we cant get them */ if ( (iError = iSrchInfoGetFieldInfo(psiSrchIndex, uiFieldID, NULL, 0, NULL, 0, NULL, &uiFieldOptions)) != SRCH_NoError ) { /* Set the field option defaults */ iSrchInfoGetFieldOptionDefaults(psiSrchIndex, &uiFieldOptions); } /* Set the field ID in the bitmap */ if ( pucFieldIDBitmap != NULL ) { /* Set the field ID in the bitmap - field ID 0 is not a field */ UTL_BITMAP_SET_BIT_IN_POINTER(pucFieldIDBitmap, uiFieldID - 1); /* Field ID bit map is set */ bFieldIDBitmapSet = true; } } } /* Check if there is an unfielded search option if the field ID bit map was not set, and if the field name is not the wildcard field name */ if ( (bFieldIDBitmapSet == false) && ((pucFieldName == NULL) || (s_strcmp(pucFieldName, SRCH_PARSER_WILDCARD_FIELD_NAME_STRING) != 0)) ) { unsigned char pucUnfieldedSearchFieldNames[SPI_FIELD_NAME_MAXIMUM_LENGTH + 1] = {"\0"}; /* Get the unfielded search field names and, if they exist, use them for this search */ if ( iSrchInfoGetUnfieldedSearchFieldNames(psiSrchIndex, pucUnfieldedSearchFieldNames, SPI_FIELD_NAME_MAXIMUM_LENGTH + 1) == SRCH_NoError ) { unsigned char *pucUnfieldedSearchFieldNamePtr = NULL; unsigned char *pucUnfieldedSearchFieldNamesStrtokPtr = NULL; /* Loop parsing the unfielded search field names */ for ( pucUnfieldedSearchFieldNamePtr = (unsigned char *)s_strtok_r(pucUnfieldedSearchFieldNames, SRCH_INFO_UNFIELDED_SEARCH_FIELD_NAMES_SEPARATORS, (char **)&pucUnfieldedSearchFieldNamesStrtokPtr); pucUnfieldedSearchFieldNamePtr != NULL; pucUnfieldedSearchFieldNamePtr = (unsigned char *)s_strtok_r(NULL, SRCH_INFO_UNFIELDED_SEARCH_FIELD_NAMES_SEPARATORS, (char **)&pucUnfieldedSearchFieldNamesStrtokPtr) ) { /* Set the field ID in the bitmap */ if ( iSrchInfoGetFieldID (psiSrchIndex, pucUnfieldedSearchFieldNamePtr, &uiFieldID) == SRCH_NoError ) { ASSERT(uiFieldID <= uiFieldIDBitmapLength); /* Set the field ID in the bitmap, we know there are fields other than field ID 0 ** since there are unfielded search field names - field ID 0 is not a field */ UTL_BITMAP_SET_BIT_IN_POINTER(pucFieldIDBitmap, uiFieldID - 1); /* Field ID bit map is set */ bFieldIDBitmapSet = true; } } } } /* Set the mixed case flag, which really means 'does this term contain upper case, or non-alphanumerics' */ bContainsUpperCase = bLngCaseDoesWideStringContainUpperCase(pwcTerm); /* Stem the term if we are stemming on this field and if the term does not end in a wildcard */ if ( (bSrchInfoFieldOptionStemming(uiFieldOptions) == true) && (bContainsUpperCase == false) && (s_wcschr(SRCH_PARSER_WILDCARDS_WSTRING , pwcTerm[s_wcslen(pwcTerm) - 1]) == NULL) ) { if ( (iError = iLngStemmerStemTerm(pvLngStemmer, pwcTerm, 0)) != LNG_NoError ) { iUtlLogError(UTL_LOG_CONTEXT, "Failed to stem a term, lng error: %d.", iError); return (SRCH_FeedbackStemmingFailed); } } /* Set the return pointers */ *ppwcTerm = pwcTerm; *pbFieldIDBitmapSet = bFieldIDBitmapSet; return (SRCH_NoError); }
/* * Create a new string list by splitting the given @c string with * the given @c separator. */ S_API s_str_list *s_str_list_split(const char *string, const char *separator, s_erc *error) { s_str_list *self = NULL; char *str_copy = NULL; char *nstr_copy; char *s; S_CLR_ERR(error); if ((string == NULL) || (separator == NULL)) goto error_return; self = s_str_list_new(error); if (S_CHK_ERR(error, S_CONTERR, "s_str_list_split", "Call to \"s_str_list_new\" failed")) goto error_return; str_copy = s_strdup(string, error); if (S_CHK_ERR(error, S_CONTERR, "s_str_list_split", "Call to \"s_strdup\" failed")) goto error_return; nstr_copy = str_copy; s = s_strtok_r(NULL, separator, &nstr_copy, error); if (S_CHK_ERR(error, S_CONTERR, "s_str_list_split", "Call to \"s_strtok_r\" failed")) goto error_return; while (s != NULL) { s_str_list_append(self, s, error); if (S_CHK_ERR(error, S_CONTERR, "s_str_list_split", "Call to \"s_str_list_append\" failed")) goto error_return; s = s_strtok_r(NULL, separator, &nstr_copy, error); if (S_CHK_ERR(error, S_CONTERR, "s_str_list_split", "Call to \"s_strtok_r\" failed")) goto error_return; } /* all OK, clean and return */ S_FREE(str_copy); return self; /* errors occurred, clean and return */ error_return: { s_erc local_err = S_FAILURE; if (str_copy != NULL) S_FREE(str_copy); if (self != NULL) s_list_delete(self, &local_err); } return NULL; }