From 0e4d2e7277bc2adf18dd1e719ec4ce684f86d72b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 20 Oct 2013 23:09:51 +0200 Subject: Util/ASCII: add function StringEqualsCaseASCII() Replaces GLib's g_ascii_strcasecmp(). --- Makefile.am | 1 + src/SongFilter.cxx | 7 ++-- src/command/OtherCommands.cxx | 5 ++- src/decoder/MadDecoderPlugin.cxx | 13 +++---- src/input/CurlInputPlugin.cxx | 15 +++++---- src/mixer/AlsaMixerPlugin.cxx | 6 ++-- src/playlist/AsxPlaylistPlugin.cxx | 13 +++---- src/playlist/EmbeddedCuePlaylistPlugin.cxx | 3 +- src/playlist/RssPlaylistPlugin.cxx | 13 +++---- src/tag/ApeReplayGain.cxx | 11 +++--- src/tag/Tag.cxx | 3 +- src/tag/TagConfig.cxx | 3 +- src/tag/TagHandler.cxx | 5 ++- src/tag/TagTable.cxx | 5 ++- src/util/ASCII.hxx | 54 ++++++++++++++++++++++++++++++ src/util/StringUtil.cxx | 5 ++- 16 files changed, 110 insertions(+), 52 deletions(-) create mode 100644 src/util/ASCII.hxx diff --git a/Makefile.am b/Makefile.am index b902e9633..36960207a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -245,6 +245,7 @@ libutil_a_SOURCES = \ src/util/Error.cxx src/util/Error.hxx \ src/util/Domain.hxx \ src/util/ReusableArray.hxx \ + src/util/ASCII.hxx \ src/util/StringUtil.cxx src/util/StringUtil.hxx \ src/util/FormatString.cxx src/util/FormatString.hxx \ src/util/Tokenizer.cxx src/util/Tokenizer.hxx \ diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx index 8874b3448..62fc8b39f 100644 --- a/src/SongFilter.cxx +++ b/src/SongFilter.cxx @@ -21,6 +21,7 @@ #include "SongFilter.hxx" #include "Song.hxx" #include "tag/Tag.hxx" +#include "util/ASCII.hxx" #include @@ -35,11 +36,11 @@ unsigned locate_parse_type(const char *str) { - if (0 == g_ascii_strcasecmp(str, LOCATE_TAG_FILE_KEY) || - 0 == g_ascii_strcasecmp(str, LOCATE_TAG_FILE_KEY_OLD)) + if (StringEqualsCaseASCII(str, LOCATE_TAG_FILE_KEY) || + StringEqualsCaseASCII(str, LOCATE_TAG_FILE_KEY_OLD)) return LOCATE_TAG_FILE_TYPE; - if (0 == g_ascii_strcasecmp(str, LOCATE_TAG_ANY_KEY)) + if (StringEqualsCaseASCII(str, LOCATE_TAG_ANY_KEY)) return LOCATE_TAG_ANY_TYPE; return tag_name_parse_i(str); diff --git a/src/command/OtherCommands.cxx b/src/command/OtherCommands.cxx index 1291caf4e..55391af16 100644 --- a/src/command/OtherCommands.cxx +++ b/src/command/OtherCommands.cxx @@ -33,6 +33,7 @@ #include "protocol/Result.hxx" #include "ls.hxx" #include "Volume.hxx" +#include "util/ASCII.hxx" #include "util/UriUtil.hxx" #include "util/Error.hxx" #include "fs/AllocatedPath.hxx" @@ -47,8 +48,6 @@ #include "StickerDatabase.hxx" #endif -#include - #include #include @@ -298,7 +297,7 @@ handle_idle(Client &client, continue; for (j = 0; idle_names[j]; ++j) { - if (!g_ascii_strcasecmp(argv[i], idle_names[j])) { + if (StringEqualsCaseASCII(argv[i], idle_names[j])) { flags |= (1 << j); } } diff --git a/src/decoder/MadDecoderPlugin.cxx b/src/decoder/MadDecoderPlugin.cxx index a6c53bfb6..260ee1900 100644 --- a/src/decoder/MadDecoderPlugin.cxx +++ b/src/decoder/MadDecoderPlugin.cxx @@ -26,6 +26,7 @@ #include "tag/TagRva2.hxx" #include "tag/TagHandler.hxx" #include "CheckAudioFormat.hxx" +#include "util/ASCII.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" #include "Log.hxx" @@ -272,16 +273,16 @@ parse_id3_replay_gain_info(struct replay_gain_info *replay_gain_info, id3_ucs4_latin1duplicate(id3_field_getstring (&frame->fields[2])); - if (g_ascii_strcasecmp(key, "replaygain_track_gain") == 0) { + if (StringEqualsCaseASCII(key, "replaygain_track_gain")) { replay_gain_info->tuples[REPLAY_GAIN_TRACK].gain = atof(value); found = true; - } else if (g_ascii_strcasecmp(key, "replaygain_album_gain") == 0) { + } else if (StringEqualsCaseASCII(key, "replaygain_album_gain")) { replay_gain_info->tuples[REPLAY_GAIN_ALBUM].gain = atof(value); found = true; - } else if (g_ascii_strcasecmp(key, "replaygain_track_peak") == 0) { + } else if (StringEqualsCaseASCII(key, "replaygain_track_peak")) { replay_gain_info->tuples[REPLAY_GAIN_TRACK].peak = atof(value); found = true; - } else if (g_ascii_strcasecmp(key, "replaygain_album_peak") == 0) { + } else if (StringEqualsCaseASCII(key, "replaygain_album_peak")) { replay_gain_info->tuples[REPLAY_GAIN_ALBUM].peak = atof(value); found = true; } @@ -321,10 +322,10 @@ parse_id3_mixramp(char **mixramp_start, char **mixramp_end, id3_ucs4_latin1duplicate(id3_field_getstring (&frame->fields[2])); - if (g_ascii_strcasecmp(key, "mixramp_start") == 0) { + if (StringEqualsCaseASCII(key, "mixramp_start")) { *mixramp_start = g_strdup(value); found = true; - } else if (g_ascii_strcasecmp(key, "mixramp_end") == 0) { + } else if (StringEqualsCaseASCII(key, "mixramp_end")) { *mixramp_end = g_strdup(value); found = true; } diff --git a/src/input/CurlInputPlugin.cxx b/src/input/CurlInputPlugin.cxx index da1dec5bd..5a754b78d 100644 --- a/src/input/CurlInputPlugin.cxx +++ b/src/input/CurlInputPlugin.cxx @@ -29,6 +29,7 @@ #include "event/MultiSocketMonitor.hxx" #include "event/Call.hxx" #include "IOThread.hxx" +#include "util/ASCII.hxx" #include "util/CharUtil.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" @@ -840,11 +841,11 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream) while (end > value && IsWhitespaceOrNull(end[-1])) --end; - if (g_ascii_strcasecmp(name, "accept-ranges") == 0) { + if (StringEqualsCaseASCII(name, "accept-ranges")) { /* a stream with icy-metadata is not seekable */ if (!c->icy.IsDefined()) c->base.seekable = true; - } else if (g_ascii_strcasecmp(name, "content-length") == 0) { + } else if (StringEqualsCaseASCII(name, "content-length")) { char buffer[64]; if ((size_t)(end - header) >= sizeof(buffer)) @@ -854,18 +855,18 @@ input_curl_headerfunction(void *ptr, size_t size, size_t nmemb, void *stream) buffer[end - value] = 0; c->base.size = c->base.offset + g_ascii_strtoull(buffer, nullptr, 10); - } else if (g_ascii_strcasecmp(name, "content-type") == 0) { + } else if (StringEqualsCaseASCII(name, "content-type")) { c->base.mime.assign(value, end); - } else if (g_ascii_strcasecmp(name, "icy-name") == 0 || - g_ascii_strcasecmp(name, "ice-name") == 0 || - g_ascii_strcasecmp(name, "x-audiocast-name") == 0) { + } else if (StringEqualsCaseASCII(name, "icy-name") || + StringEqualsCaseASCII(name, "ice-name") || + StringEqualsCaseASCII(name, "x-audiocast-name")) { c->meta_name.assign(value, end); delete c->tag; c->tag = new Tag(); c->tag->AddItem(TAG_NAME, c->meta_name.c_str()); - } else if (g_ascii_strcasecmp(name, "icy-metaint") == 0) { + } else if (StringEqualsCaseASCII(name, "icy-metaint")) { char buffer[64]; size_t icy_metaint; diff --git a/src/mixer/AlsaMixerPlugin.cxx b/src/mixer/AlsaMixerPlugin.cxx index 05d70c4c0..f651e94ce 100644 --- a/src/mixer/AlsaMixerPlugin.cxx +++ b/src/mixer/AlsaMixerPlugin.cxx @@ -24,6 +24,7 @@ #include "Main.hxx" #include "event/MultiSocketMonitor.hxx" #include "event/Loop.hxx" +#include "util/ASCII.hxx" #include "util/ReusableArray.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" @@ -31,7 +32,6 @@ #include -#include #include #define VOLUME_MIXER_ALSA_DEFAULT "default" @@ -197,8 +197,8 @@ alsa_mixer_lookup_elem(snd_mixer_t *handle, const char *name, unsigned idx) for (snd_mixer_elem_t *elem = snd_mixer_first_elem(handle); elem != NULL; elem = snd_mixer_elem_next(elem)) { if (snd_mixer_elem_get_type(elem) == SND_MIXER_ELEM_SIMPLE && - g_ascii_strcasecmp(snd_mixer_selem_get_name(elem), - name) == 0 && + StringEqualsCaseASCII(snd_mixer_selem_get_name(elem), + name) && snd_mixer_selem_get_index(elem) == idx) return elem; } diff --git a/src/playlist/AsxPlaylistPlugin.cxx b/src/playlist/AsxPlaylistPlugin.cxx index ab204773f..14063fdf2 100644 --- a/src/playlist/AsxPlaylistPlugin.cxx +++ b/src/playlist/AsxPlaylistPlugin.cxx @@ -24,6 +24,7 @@ #include "InputStream.hxx" #include "Song.hxx" #include "tag/Tag.hxx" +#include "util/ASCII.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" #include "Log.hxx" @@ -75,7 +76,7 @@ get_attribute(const gchar **attribute_names, const gchar **attribute_values, const gchar *name) { for (unsigned i = 0; attribute_names[i] != NULL; ++i) - if (g_ascii_strcasecmp(attribute_names[i], name) == 0) + if (StringEqualsCaseASCII(attribute_names[i], name)) return attribute_values[i]; return NULL; @@ -92,7 +93,7 @@ asx_start_element(gcc_unused GMarkupParseContext *context, switch (parser->state) { case AsxParser::ROOT: - if (g_ascii_strcasecmp(element_name, "entry") == 0) { + if (StringEqualsCaseASCII(element_name, "entry")) { parser->state = AsxParser::ENTRY; parser->song = Song::NewRemote("asx:"); parser->tag = TAG_NUM_OF_ITEM_TYPES; @@ -101,7 +102,7 @@ asx_start_element(gcc_unused GMarkupParseContext *context, break; case AsxParser::ENTRY: - if (g_ascii_strcasecmp(element_name, "ref") == 0) { + if (StringEqualsCaseASCII(element_name, "ref")) { const gchar *href = get_attribute(attribute_names, attribute_values, "href"); @@ -121,11 +122,11 @@ asx_start_element(gcc_unused GMarkupParseContext *context, parser->song = song; } - } else if (g_ascii_strcasecmp(element_name, "author") == 0) + } else if (StringEqualsCaseASCII(element_name, "author")) /* is that correct? or should it be COMPOSER or PERFORMER? */ parser->tag = TAG_ARTIST; - else if (g_ascii_strcasecmp(element_name, "title") == 0) + else if (StringEqualsCaseASCII(element_name, "title")) parser->tag = TAG_TITLE; break; @@ -144,7 +145,7 @@ asx_end_element(gcc_unused GMarkupParseContext *context, break; case AsxParser::ENTRY: - if (g_ascii_strcasecmp(element_name, "entry") == 0) { + if (StringEqualsCaseASCII(element_name, "entry")) { if (strcmp(parser->song->uri, "asx:") != 0) parser->songs.emplace_front(parser->song); else diff --git a/src/playlist/EmbeddedCuePlaylistPlugin.cxx b/src/playlist/EmbeddedCuePlaylistPlugin.cxx index fe3b4ca12..50390dbd6 100644 --- a/src/playlist/EmbeddedCuePlaylistPlugin.cxx +++ b/src/playlist/EmbeddedCuePlaylistPlugin.cxx @@ -35,6 +35,7 @@ #include "TagFile.hxx" #include "cue/CueParser.hxx" #include "fs/Traits.hxx" +#include "util/ASCII.hxx" #include #include @@ -81,7 +82,7 @@ embcue_tag_pair(const char *name, const char *value, void *ctx) EmbeddedCuePlaylist *playlist = (EmbeddedCuePlaylist *)ctx; if (playlist->cuesheet == NULL && - g_ascii_strcasecmp(name, "cuesheet") == 0) + StringEqualsCaseASCII(name, "cuesheet")) playlist->cuesheet = g_strdup(value); } diff --git a/src/playlist/RssPlaylistPlugin.cxx b/src/playlist/RssPlaylistPlugin.cxx index 7faf6faac..4aa6f1026 100644 --- a/src/playlist/RssPlaylistPlugin.cxx +++ b/src/playlist/RssPlaylistPlugin.cxx @@ -24,6 +24,7 @@ #include "InputStream.hxx" #include "Song.hxx" #include "tag/Tag.hxx" +#include "util/ASCII.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" #include "Log.hxx" @@ -74,7 +75,7 @@ get_attribute(const gchar **attribute_names, const gchar **attribute_values, const gchar *name) { for (unsigned i = 0; attribute_names[i] != NULL; ++i) - if (g_ascii_strcasecmp(attribute_names[i], name) == 0) + if (StringEqualsCaseASCII(attribute_names[i], name)) return attribute_values[i]; return NULL; @@ -91,7 +92,7 @@ rss_start_element(gcc_unused GMarkupParseContext *context, switch (parser->state) { case RssParser::ROOT: - if (g_ascii_strcasecmp(element_name, "item") == 0) { + if (StringEqualsCaseASCII(element_name, "item")) { parser->state = RssParser::ITEM; parser->song = Song::NewRemote("rss:"); parser->tag = TAG_NUM_OF_ITEM_TYPES; @@ -100,7 +101,7 @@ rss_start_element(gcc_unused GMarkupParseContext *context, break; case RssParser::ITEM: - if (g_ascii_strcasecmp(element_name, "enclosure") == 0) { + if (StringEqualsCaseASCII(element_name, "enclosure")) { const gchar *href = get_attribute(attribute_names, attribute_values, "url"); @@ -120,9 +121,9 @@ rss_start_element(gcc_unused GMarkupParseContext *context, parser->song = song; } - } else if (g_ascii_strcasecmp(element_name, "title") == 0) + } else if (StringEqualsCaseASCII(element_name, "title")) parser->tag = TAG_TITLE; - else if (g_ascii_strcasecmp(element_name, "itunes:author") == 0) + else if (StringEqualsCaseASCII(element_name, "itunes:author")) parser->tag = TAG_ARTIST; break; @@ -141,7 +142,7 @@ rss_end_element(gcc_unused GMarkupParseContext *context, break; case RssParser::ITEM: - if (g_ascii_strcasecmp(element_name, "item") == 0) { + if (StringEqualsCaseASCII(element_name, "item")) { if (strcmp(parser->song->uri, "rss:") != 0) parser->songs.emplace_front(parser->song); else diff --git a/src/tag/ApeReplayGain.cxx b/src/tag/ApeReplayGain.cxx index 817eca349..15526d2d9 100644 --- a/src/tag/ApeReplayGain.cxx +++ b/src/tag/ApeReplayGain.cxx @@ -21,8 +21,7 @@ #include "ApeReplayGain.hxx" #include "ApeLoader.hxx" #include "ReplayGainInfo.hxx" - -#include +#include "util/ASCII.hxx" #include #include @@ -43,16 +42,16 @@ replay_gain_ape_callback(unsigned long flags, const char *key, memcpy(value, _value, value_length); value[value_length] = 0; - if (g_ascii_strcasecmp(key, "replaygain_track_gain") == 0) { + if (StringEqualsCaseASCII(key, "replaygain_track_gain")) { info->tuples[REPLAY_GAIN_TRACK].gain = atof(value); return true; - } else if (g_ascii_strcasecmp(key, "replaygain_album_gain") == 0) { + } else if (StringEqualsCaseASCII(key, "replaygain_album_gain")) { info->tuples[REPLAY_GAIN_ALBUM].gain = atof(value); return true; - } else if (g_ascii_strcasecmp(key, "replaygain_track_peak") == 0) { + } else if (StringEqualsCaseASCII(key, "replaygain_track_peak")) { info->tuples[REPLAY_GAIN_TRACK].peak = atof(value); return true; - } else if (g_ascii_strcasecmp(key, "replaygain_album_peak") == 0) { + } else if (StringEqualsCaseASCII(key, "replaygain_album_peak")) { info->tuples[REPLAY_GAIN_ALBUM].peak = atof(value); return true; } else diff --git a/src/tag/Tag.cxx b/src/tag/Tag.cxx index 6ff8b3dc9..6bf070429 100644 --- a/src/tag/Tag.cxx +++ b/src/tag/Tag.cxx @@ -22,6 +22,7 @@ #include "TagPool.hxx" #include "TagString.hxx" #include "TagSettings.h" +#include "util/ASCII.hxx" #include #include @@ -50,7 +51,7 @@ tag_name_parse_i(const char *name) for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i) { assert(tag_item_names[i] != nullptr); - if (g_ascii_strcasecmp(name, tag_item_names[i]) == 0) + if (StringEqualsCaseASCII(name, tag_item_names[i])) return (TagType)i; } diff --git a/src/tag/TagConfig.cxx b/src/tag/TagConfig.cxx index 9e47cd05b..96fd1847f 100644 --- a/src/tag/TagConfig.cxx +++ b/src/tag/TagConfig.cxx @@ -24,6 +24,7 @@ #include "ConfigGlobal.hxx" #include "ConfigOption.hxx" #include "system/FatalError.hxx" +#include "util/ASCII.hxx" #include @@ -40,7 +41,7 @@ TagLoadConfig() std::fill_n(ignore_tag_items, TAG_NUM_OF_ITEM_TYPES, true); - if (0 == g_ascii_strcasecmp(value, "none")) + if (StringEqualsCaseASCII(value, "none")) return; bool quit = false; diff --git a/src/tag/TagHandler.cxx b/src/tag/TagHandler.cxx index 9e31a7d1d..80982ef50 100644 --- a/src/tag/TagHandler.cxx +++ b/src/tag/TagHandler.cxx @@ -20,8 +20,7 @@ #include "config.h" #include "TagHandler.hxx" #include "TagBuilder.hxx" - -#include +#include "util/ASCII.hxx" static void add_tag_duration(unsigned seconds, void *ctx) @@ -50,7 +49,7 @@ full_tag_pair(const char *name, gcc_unused const char *value, void *ctx) { TagBuilder &tag = *(TagBuilder *)ctx; - if (g_ascii_strcasecmp(name, "cuesheet") == 0) + if (StringEqualsCaseASCII(name, "cuesheet")) tag.SetHasPlaylist(true); } diff --git a/src/tag/TagTable.cxx b/src/tag/TagTable.cxx index c7e920f2e..b51bc35ba 100644 --- a/src/tag/TagTable.cxx +++ b/src/tag/TagTable.cxx @@ -18,8 +18,7 @@ */ #include "TagTable.hxx" - -#include +#include "util/ASCII.hxx" #include @@ -47,7 +46,7 @@ TagType tag_table_lookup_i(const struct tag_table *table, const char *name) { for (; table->name != nullptr; ++table) - if (g_ascii_strcasecmp(name, table->name) == 0) + if (StringEqualsCaseASCII(name, table->name)) return table->type; return TAG_NUM_OF_ITEM_TYPES; diff --git a/src/util/ASCII.hxx b/src/util/ASCII.hxx new file mode 100644 index 000000000..0d4c8f35b --- /dev/null +++ b/src/util/ASCII.hxx @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2013 Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef MPD_ASCII_HXX +#define MPD_ASCII_HXX + +#include "Compiler.h" + +#include +#include + +/** + * Determine whether two strings are equal, ignoring case for ASCII + * letters. + */ +gcc_pure gcc_nonnull_all +static inline bool +StringEqualsCaseASCII(const char *a, const char *b) +{ + assert(a != nullptr); + assert(b != nullptr); + + /* note: strcasecmp() depends on the locale, but for ASCII-only + strings, it's safe to use */ + return strcasecmp(a, b) == 0; +} + +#endif diff --git a/src/util/StringUtil.cxx b/src/util/StringUtil.cxx index 048f009f5..7e295bf90 100644 --- a/src/util/StringUtil.cxx +++ b/src/util/StringUtil.cxx @@ -19,8 +19,7 @@ #include "StringUtil.hxx" #include "CharUtil.hxx" - -#include +#include "ASCII.hxx" #include @@ -40,7 +39,7 @@ string_array_contains(const char *const* haystack, const char *needle) assert(needle != nullptr); for (; *haystack != nullptr; ++haystack) - if (g_ascii_strcasecmp(*haystack, needle) == 0) + if (StringEqualsCaseASCII(*haystack, needle)) return true; return false; -- cgit v1.2.3