core/string: Move string_lowercase() out of "string" namespace

And refactor to use glib string functions while we're at it.

Signed-off-by: Anna Schumaker <Anna@OcarinaProject.net>
This commit is contained in:
Anna Schumaker 2015-09-08 09:14:39 -04:00
parent 83fe822dc7
commit 1a3735251d
5 changed files with 59 additions and 85 deletions

View File

@ -12,9 +12,12 @@ static Index filter_index("", false);
const std::string filter :: add(const std::string &text, unsigned int index)
{
const std::string lc = string :: lowercase(text);
gchar *g_lc = string_lowercase(text.c_str());
const std::string lc = g_lc;
size_t begin = 0, end;
g_free(g_lc);
for (end = 1; end <= lc.size(); end++) {
filter_index.insert(lc.substr(begin, end - begin), index);
if (lc[end] == ' ')
@ -35,10 +38,12 @@ static void do_set_intersection(IndexEntry *entry,
void filter :: search(const std::string &text, std::set<unsigned int> &res)
{
const std::string lc = string :: lowercase(text);
gchar *g_lc = string_lowercase(text.c_str());
const std::string lc = g_lc;
size_t begin = 0, end;
IndexEntry *found;
g_free(g_lc);
res.clear();
for (end = 1; end <= lc.size(); end++) {

View File

@ -1,7 +1,8 @@
/**
/*
* Copyright 2015 (c) Anna Schumaker.
*/
#include <core/string.h>
#include <string.h>
#define O_SECONDS (1)
#define O_MINUTES (60)
@ -39,51 +40,28 @@ gchar *string_sec2str_long(unsigned int sec)
return res;
}
static char _to_lower(char c)
static void _drop_special(gchar *str)
{
if ((c >= 'a') && (c <= 'z'))
return c;
if ((c >= '0') && (c <= '9'))
return c;
if ((c >= 'A') && (c <= 'Z'))
return c + ('a' - 'A');
unsigned int i, j = 0;
switch (c) {
case '\\':
case '/':
case ',':
case ';':
case '(':
case ')':
case '_':
case '-':
case '~':
case '+':
case '"':
case ' ':
case ' ':
return ' ';
default:
return 0;
}
}
const std::string string :: lowercase(const std::string &str)
{
std::string ret;
char c, last = ' ';
for (unsigned int i = 0; i < str.size(); i++) {
c = _to_lower(str[i]);
if (c > 0) {
if ((c != ' ') || (last != ' '))
ret += c;
last = c;
}
for (i = 0; i < strlen(str); i++) {
if (g_ascii_isalnum(str[i]))
str[j++] = str[i];
else if ((j > 0) && (str[i] == ' ') && (str[j - 1] != ' '))
str[j++] = str[i];
}
if (ret[ret.size() - 1] == ' ')
return ret.substr(0, ret.size() - 1);
return ret;
while (j < i)
str[j++] = '\0';
}
gchar *string_lowercase(const gchar *str)
{
gchar *res = g_ascii_strdown(str, -1);
g_strdelimit(res, "\\/,;()_-~+\" ", ' ');
_drop_special(res);
g_strstrip(res);
return res;
}

View File

@ -7,8 +7,11 @@
GenericTag :: GenericTag() {}
GenericTag :: GenericTag(const std::string &name)
: _name(name), _lower(string :: lowercase(name))
: _name(name)
{
gchar *g_lc = string_lowercase(name.c_str());
_lower = g_lc;
g_free(g_lc);
}
GenericTag :: GenericTag(const GenericTag &tag)
@ -23,8 +26,12 @@ const std::string GenericTag :: primary_key() const
void GenericTag :: read(File &file)
{
gchar *g_lc;
_name = file.getline();
_lower = string :: lowercase(_name);
g_lc = string_lowercase(_name.c_str());
_lower = g_lc;
g_free(g_lc);
}
void GenericTag :: write(File &file)

View File

@ -1,38 +1,22 @@
/**
/*
* Copyright 2015 (c) Anna Schumaker.
*
* NOTE: All of these functions allocate and return a new string. It is the
* caller's responsibility to free these strings by calling g_free().
*/
#ifndef OCARINA_CORE_STRING_H
#define OCARINA_CORE_STRING_H
#include <glib.h>
#include <string>
/**
* Namespace for string formatting functions.
*/
namespace string
{
/**
* Convert a string to lowercase, stripping out special characters
* along the way.
* @param str Input string.
* @return The same string converted to lowercase.
*/
const std::string lowercase(const std::string &);
}
/*
* Convert number of seconds into a string with format mm:ss.
* This function allocates a new string that MUST be freed with g_free().
*/
/* Convert number of seconds into a string with format mm:ss. */
gchar *string_sec2str(unsigned int);
/*
* Convert number of seconds into a long-form time string.
* This function allocates a new string that MUST be freed with g_free().
*/
/* Convert number of seconds into a long-form time string. */
gchar *string_sec2str_long(unsigned int);
/* Convert the input string to lowercase, dropping special characters. */
gchar *string_lowercase(const gchar *);
#endif /* OCARINA_CORE_STRING_H */

View File

@ -56,19 +56,19 @@ void test_sec2str_long()
void test_lowercase()
{
test_equal(string :: lowercase(" "), "");
test_equal(string :: lowercase(" test \
text"), "test text");
test_equal(string :: lowercase("test/text"), "test text");
test_equal(string :: lowercase("Test, Text"), "test text");
test_equal(string :: lowercase("Test? Text!"), "test text");
test_equal(string :: lowercase("Test?123 Text!456"), "test123 text456");
test_equal(string :: lowercase("Test?123 Text!456"), "test123 text456");
test_equal(string :: lowercase("Test(text);123-456"), "test text 123 456");
test_equal(string :: lowercase("Test((text));;123--456"), "test text 123 456");
test_equal(string :: lowercase("! __test(TEXT) + __test(\"TEXT\")"),
test_equal(swap(string_lowercase(" ")), "");
test_equal(swap(string_lowercase(" test \
text")), "test text");
test_equal(swap(string_lowercase("test/text")), "test text");
test_equal(swap(string_lowercase("Test, Text")), "test text");
test_equal(swap(string_lowercase("Test? Text!")), "test text");
test_equal(swap(string_lowercase("Test?123 Text!456")), "test123 text456");
test_equal(swap(string_lowercase("Test?123 Text!456")), "test123 text456");
test_equal(swap(string_lowercase("Test(text);123-456")), "test text 123 456");
test_equal(swap(string_lowercase("Test((text));;123--456")), "test text 123 456");
test_equal(swap(string_lowercase("! __test(TEXT) + __test(\"TEXT\")")),
"test text test text");
test_equal(string :: lowercase("Test~tEXt\\123"), "test text 123");
test_equal(swap(string_lowercase("Test~tEXt\\123")), "test text 123");
}