int type_elementary_identifier_p(const struct RFstring *id) { const struct gperf_elementary_type *etype; // assert that the array size is same as enum size BUILD_ASSERT( sizeof(elementary_type_strings)/sizeof(struct RFstring) == ELEMENTARY_TYPE_TYPES_COUNT ); etype = types_string_is_elementary(rf_string_data(id), rf_string_length_bytes(id)); if (!etype) { return -1; } return etype->type; }
} END_TEST START_TEST (test_RFS_NT) { struct RFstring *s1 = RFS_NT("a string"); struct RFstring *s2 = RFS_NT("a string %s %d", "with", 123); ck_assert_rf_str_eq_cstr(s1, "a string"); ck_assert(rf_string_data(s1)[rf_string_length_bytes(s1)] == '\0'); ck_assert_rf_str_eq_cstr(s2, "a string with 123"); ck_assert(rf_string_data(s2)[rf_string_length_bytes(s2)] == '\0'); struct RFstring *s3 = RFS_NT_OR_DIE("a string"); struct RFstring *s4 = RFS_NT("a string %s %d", "with", 123); ck_assert_rf_str_eq_cstr(s3, "a string"); ck_assert(rf_string_data(s3)[rf_string_length_bytes(s3)] == '\0'); ck_assert_rf_str_eq_cstr(s4, "a string with 123"); ck_assert(rf_string_data(s4)[rf_string_length_bytes(s4)] == '\0'); // test that subsequent allocations don't overwite the null terminating // character ck_assert(rf_string_data(s1)[rf_string_length_bytes(s1)] == '\0'); ck_assert(rf_string_data(s2)[rf_string_length_bytes(s2)] == '\0'); ck_assert(rf_string_data(s3)[rf_string_length_bytes(s3)] == '\0'); ck_assert(rf_string_data(s4)[rf_string_length_bytes(s4)] == '\0'); } END_TEST
}END_TEST START_TEST(test_stringx_skip_chars) { struct RFstringx s; unsigned int bytes; unsigned int line_count; static const struct RFstring s1 = RF_STRING_STATIC_INIT(" \t something"); static const struct RFstring chars1 = RF_STRING_STATIC_INIT(" \t"); static const struct RFstring s2 = RF_STRING_STATIC_INIT( " ブ ブ ラ something_else"); static const struct RFstring chars2 = RF_STRING_STATIC_INIT(" ブラ"); static const struct RFstring s3 = RF_STRING_STATIC_INIT( " \n \n \t foo"); static const struct RFstring chars3 = RF_STRING_STATIC_INIT(" \t\n"); static const struct RFstring s4 = RF_STRING_STATIC_INIT( "not skipping \t \n \n"); ck_assert(rf_stringx_init_buff(&s, 1024, "")); ck_assert(rf_stringx_assign(&s, &s1)); ck_assert_int_eq(6, rf_stringx_skip_chars(&s, &chars1, 0, &bytes, 0)); ck_assert_int_eq(6, bytes); ck_assert_rf_str_eq_cstr(&s, "something"); ck_assert(rf_stringx_assign(&s, &s2)); ck_assert_int_eq(7, rf_stringx_skip_chars(&s, &chars2, 0, &bytes, 0)); ck_assert_int_eq(13, bytes); ck_assert_rf_str_eq_cstr(&s, "something_else"); ck_assert(rf_stringx_assign(&s, &s3)); ck_assert_int_eq(8, rf_stringx_skip_chars(&s, &chars3, 0, &bytes, &line_count)); ck_assert_int_eq(8, bytes); ck_assert_int_eq(2, line_count); ck_assert_rf_str_eq_cstr(&s, "foo"); ck_assert(rf_stringx_assign(&s, &s3)); ck_assert_int_eq(3, rf_stringx_skip_chars(&s, &chars3, rf_string_data(&s) + 2, &bytes, &line_count)); ck_assert_int_eq(3, bytes); ck_assert_int_eq(1, line_count); ck_assert_rf_str_eq_cstr(&s," \n \t foo"); ck_assert(rf_stringx_assign(&s, &s3)); ck_assert_int_eq(1, rf_stringx_skip_chars(&s, &chars3, rf_string_data(&s), &bytes, &line_count)); ck_assert_int_eq(1, bytes); ck_assert_int_eq(0, line_count); ck_assert_rf_str_eq_cstr(&s,"\n \n \t foo"); ck_assert(rf_stringx_assign(&s, &s4)); ck_assert_int_eq(0, rf_stringx_skip_chars(&s, &chars3, 0, &bytes, &line_count)); ck_assert_int_eq(0, bytes); ck_assert_int_eq(0, line_count); rf_stringx_deinit(&s); }END_TEST
// Internal version of rf_string_find, used for byte position. int rf_string_find_byte_pos(const struct RFstring *tstr, const struct RFstring *sstr, const char options) { #define CHECK_NOT_CHAR(s_, i_) \ do{ \ /* if is is not a character */ \ switch(rf_string_data(s_)[i_]) \ { \ case ' ':case '\t':case '\n': \ break; \ default: \ return RF_FAILURE; \ break; \ } \ }while(0) const char* found = 0; RF_ASSERT(tstr, "got null string in function"); if (!sstr) { RF_WARNING("Provided null search string parameter"); return RF_FAILURE; } //search matching characters if(!RF_BITFLAG_ON(options, RF_CASE_IGNORE)) { //if it is not found if(!(found = strstr_nnt(rf_string_data(tstr), rf_string_length_bytes(tstr), rf_string_data(sstr), rf_string_length_bytes(sstr)))) return RF_FAILURE; //get the byte position uint32_t bytepos = found - rf_string_data(tstr); //if we need the exact string as it is given if(RF_BITFLAG_ON(options, RF_MATCH_WORD)) { //check before the found string if(bytepos != 0) { CHECK_NOT_CHAR(tstr, bytepos - 1); } //check after the found string if(bytepos + rf_string_length_bytes(sstr) != rf_string_length_bytes(tstr)) { //if is is not a character CHECK_NOT_CHAR(tstr, bytepos + rf_string_length_bytes(sstr)); } }//end of the exact string option //else return the position in the bytes buffer return bytepos; } //else, case insensitive search uint32_t i,j; for(i=0; i < rf_string_length_bytes(tstr); i ++) { //if i matches the start of the substring for(j = 0; j < rf_string_length_bytes(sstr); j++) { //if the jth char is a big letter if(rf_string_data(sstr)[j] >= 0x41 && rf_string_data(sstr)[j] <= 0x5a) { //no match if(rf_string_data(sstr)[j] != rf_string_data(tstr)[i+j] && rf_string_data(sstr)[j]+32 != rf_string_data(tstr)[i+j]) break; //there is a match in the jth character if(RF_BITFLAG_ON(options, RF_MATCH_WORD)) { /* if it's the first substring character and if the string we search is not in it's beginning, check for EXACT string before */ if(j == 0 && i != 0) { CHECK_NOT_CHAR(tstr, i - 1); } }//exact string check if ends } //small letter else if(rf_string_data(sstr)[j] >= 0x61 && rf_string_data(sstr)[j] <= 0x7a) { //no match if(rf_string_data(sstr)[j] != rf_string_data(tstr)[i+j] && rf_string_data(sstr)[j]-32 != rf_string_data(tstr)[i+j]) break; //there is a match in the jth character if(RF_BITFLAG_ON(options, RF_MATCH_WORD)) { /* if it's the first substring character and if the string we search is not in it's beginning, check for EXACT string before */ if(j == 0 && i != 0) { CHECK_NOT_CHAR(tstr, i - 1); } }//exact string check if ends } //not a letter and no match else if(rf_string_data(sstr)[j] != rf_string_data(tstr)[i+j]) { break;//break off the substring search loop } //we either found it or need to perform one last check for exact string if(j == rf_string_length_bytes(sstr) - 1) { //only if the end of the string is not right after the substring if(RF_BITFLAG_ON(options, RF_MATCH_WORD) && i + rf_string_length_bytes(sstr) < rf_string_length_bytes(tstr)) { CHECK_NOT_CHAR(tstr, i + rf_string_length_bytes(sstr)); }//end of the exact string check //succes return i; }//end of it's the last char of the substring check }//substring iteration ends }//this string iteration ends return RF_FAILURE; //getting here means nothing was found #undef CHECK_NOT_CHAR }