diff --git a/Radio.cpp b/Radio.cpp index 4eecd931e..c6175634e 100644 --- a/Radio.cpp +++ b/Radio.cpp @@ -17,6 +17,10 @@ namespace Radio // very loose validation - callsign must contain a letter next to // a number QRegularExpression valid_callsign_regexp {R"(\d[[:alpha:]]|[[:alpha:]]\d)"}; + + // suffixes that are often used and should not be interpreted as a + // DXCC Entity prefix used as a suffix + QRegularExpression non_prefix_suffix {R"(\A([0-9AMPQR]|QRP|F[DF]|[AM]M|L[HT]|LGT)\z)"}; } @@ -125,6 +129,34 @@ namespace Radio callsign = callsign.left (slash_pos); } } - return callsign; + return callsign.toUpper (); + } + + // analyze the callsign and determine the effective prefix, returns + // the full call if no valid prefix (or prefix as a suffix) is specified + QString effective_prefix (QString callsign) + { + auto prefix = callsign.toUpper (); + auto slash_pos = callsign.indexOf ('/'); + if (slash_pos >= 0) + { + auto right_size = callsign.size () - slash_pos - 1; + if (right_size >= slash_pos) // naive call is longer than + // prefix/suffix algorithm + { + prefix = callsign.left (slash_pos); + } + else + { + prefix = callsign.mid (slash_pos + 1); + if (prefix.contains (non_prefix_suffix)) + { + prefix = callsign.left (slash_pos); // ignore + // non-prefix + // suffixes + } + } + } + return prefix; } } diff --git a/Radio.hpp b/Radio.hpp index b8eec22a7..7f8b0a0f4 100644 --- a/Radio.hpp +++ b/Radio.hpp @@ -54,6 +54,7 @@ namespace Radio bool UDP_EXPORT is_callsign (QString const&); bool UDP_EXPORT is_compound_callsign (QString const&); QString UDP_EXPORT base_callsign (QString); + QString UDP_EXPORT effective_prefix (QString); } Q_DECLARE_METATYPE (Radio::Frequency); diff --git a/logbook/countrydat.cpp b/logbook/countrydat.cpp index b66f0664e..d1997a977 100644 --- a/logbook/countrydat.cpp +++ b/logbook/countrydat.cpp @@ -19,6 +19,7 @@ #include #include #include +#include "Radio.hpp" void CountryDat::init(const QString filename) { @@ -131,14 +132,15 @@ QString CountryDat::find(QString call) const return fixup (_data.value ("=" + call), call); } - auto prefix = call; - while (prefix.size () >= 1) + auto prefix = Radio::effective_prefix (call); + auto match_candidate = prefix; + while (match_candidate.size () >= 1) { - if (_data.contains (prefix)) + if (_data.contains (match_candidate)) { - return fixup (_data.value (prefix), call); + return fixup (_data.value (match_candidate), prefix); } - prefix = prefix.left (prefix.size () - 1); + match_candidate = match_candidate.left (match_candidate.size () - 1); } return QString {}; } @@ -150,7 +152,7 @@ QString CountryDat::fixup (QString country, QString const& call) const // // KG4 2x1 and 2x3 calls that map to Gitmo are mainland US not Gitmo - if (call.startsWith ("KG4") && call.size () != 5) + if (call.startsWith ("KG4") && call.size () != 5 && call.size () != 3) { country.replace ("Guantanamo Bay; KG4; NA", "United States; K; NA"); }