From 2686da545132fe12ce5b8b2bd7b6da18f6dacd70 Mon Sep 17 00:00:00 2001 From: Ervin Hegedus Date: Mon, 7 Mar 2022 23:43:43 +0100 Subject: [PATCH 01/10] Added RESENDCALL feature --- src/globalvars.h | 2 ++ src/logit.c | 22 ++++++++++++++ src/main.c | 4 +++ src/parse_logcfg.c | 19 ++++++++++++ src/sendbuf.c | 3 ++ src/tlf.h | 7 +++++ src/utils.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++ src/utils.h | 1 + tlf.1.in | 12 ++++++++ 9 files changed, 145 insertions(+) diff --git a/src/globalvars.h b/src/globalvars.h index b642c3f56..1fbe9de1d 100644 --- a/src/globalvars.h +++ b/src/globalvars.h @@ -52,6 +52,8 @@ extern bool country_mult; extern struct qso_t *current_qso; extern char hiscall[20]; extern char hiscall_sent[20]; +extern int resend_call; +extern char sentcall[20]; extern int total; extern int qso_points; extern int qsos_per_band[NBANDS]; diff --git a/src/logit.c b/src/logit.c index 8a9a595c9..56570bfd6 100644 --- a/src/logit.c +++ b/src/logit.c @@ -48,6 +48,7 @@ #include "tlf_curses.h" #include "ui_utils.h" #include "cleanup.h" +#include "utils.h" void refresh_comment(void); @@ -166,6 +167,27 @@ void logit(void) { callreturn = 0; } else if (defer_store > 1) { if ((cqmode == CQ) && iscontest) { + if (cqmode == CQ && resend_call != RESEND_NOT_SET) { + if (strcmp(hiscall, sentcall) != 0) { + char tempmsg[21] = ""; + char partial_call[20]; + switch (resend_call) { + case RESEND_FULL: + sprintf(tempmsg, "%s ", hiscall); + break; + case RESEND_PARTIAL: + get_partial_callsign(sentcall, hiscall, partial_call); + sprintf(tempmsg, "%s ", partial_call); + break; + default: + break; + } + if (tempmsg[0] != '\0') { + sendmessage(tempmsg); + } + } + sentcall[0] = '\0'; + } send_standard_message(CQ_TU_MSG); /* send cq return */ set_simulator_state(CALL); diff --git a/src/main.c b/src/main.c index fe0c41a77..cf5bf105e 100644 --- a/src/main.c +++ b/src/main.c @@ -441,6 +441,10 @@ static const struct argp_option options[] = { { 0 } }; +/* resend call option, can be 0 (do not use), 1 (partial), 2 (full) */ +int resend_call = RESEND_NOT_SET; +char sentcall[20] = ""; // storing the call what already sent + /* parse a single option */ static error_t parse_opt(int key, char *arg, struct argp_state *state) { switch (key) { diff --git a/src/parse_logcfg.c b/src/parse_logcfg.c index 0010a45c1..7a838ef87 100644 --- a/src/parse_logcfg.c +++ b/src/parse_logcfg.c @@ -1025,6 +1025,24 @@ static int cfg_cabrillo_field(const cfg_arg_t arg) { return rc; } +static int cfg_resend_call(const cfg_arg_t arg) { + char *str = g_ascii_strup(parameter, -1); + g_strstrip(str); + + if (strcmp(str, "PARTIAL") == 0) { + resend_call = RESEND_PARTIAL; + } else if (strcmp(str, "FULL") == 0) { + resend_call = RESEND_FULL; + } else { + g_free(str); + error_details = g_strdup("must be PARTIAL or FULL"); + return PARSE_WRONG_PARAMETER; + } + + g_free(str); + return PARSE_OK; +} + static config_t logcfg_configs[] = { {"CONTEST_MODE", CFG_BOOL_TRUE(iscontest)}, {"MIXED", CFG_BOOL_TRUE(mixedmode)}, @@ -1189,6 +1207,7 @@ static config_t logcfg_configs[] = { {"UNIQUE_CALL_MULTI", NEED_PARAM, cfg_unique_call_multi}, {"DIGI_RIG_MODE", NEED_PARAM, cfg_digi_rig_mode}, {"CABRILLO-(.+)", OPTIONAL_PARAM, cfg_cabrillo_field}, + {"RESENDCALL", NEED_PARAM, cfg_resend_call}, {NULL} // end marker }; diff --git a/src/sendbuf.c b/src/sendbuf.c index 83615ac22..97fb31405 100644 --- a/src/sendbuf.c +++ b/src/sendbuf.c @@ -182,6 +182,9 @@ void ExpandMacro(void) { early_started = 0; // sending_call = 0; } + if (cqmode == CQ && resend_call != RESEND_NOT_SET) { + strcpy(sentcall, hiscall); + } replace_1(buffer, BUFSIZE, "@", p); /* his call, 1st occurrence */ replace_all(buffer, BUFSIZE, "@", hiscall); /* his call, further occurrences */ diff --git a/src/tlf.h b/src/tlf.h index e57d3dea4..e218fbcb7 100644 --- a/src/tlf.h +++ b/src/tlf.h @@ -283,6 +283,13 @@ enum { MARKER_CALLS, /* DOTS & CALLS */ }; +/* Enums for RESENDCALL feature */ +enum { + RESEND_NOT_SET, /* Resend feature not set */ + RESEND_PARTIAL, /* Resend partial hiscall */ + RESEND_FULL, /* Resend full hiscall again */ +}; + #define FREE_DYNAMIC_STRING(p) if (p != NULL) {g_free(p); p = NULL;} #define LEN(array) (sizeof(array) / sizeof(array[0])) diff --git a/src/utils.c b/src/utils.c index 30c66c9a8..fdcdc877d 100644 --- a/src/utils.c +++ b/src/utils.c @@ -20,6 +20,9 @@ #include #include #include +#include + +#include "getpx.h" /* \brief find named file in actual directory or in share * @@ -42,4 +45,76 @@ char *find_available(char *filename) { return path; } +/* \brief get a substring from corrected call to repeat it + * + * \returns a substring based on the sent and corrected callsign + */ +void get_partial_callsign(char *call1, char *call2, char *partial) { + + size_t len1 = strlen(call1), len2 = strlen(call2); + unsigned int len = (len1 < len2) ? len1 : len2; + unsigned int i; + unsigned int plen, plen1, plen2; + int min = -1, max = -1; + char tpartial[20]; + + + tpartial[0] = '\0'; + + char *pfx1 = get_wpx_pfx(call1); + char *pfx2 = get_wpx_pfx(call2); + + plen1 = strlen(pfx1); + plen2 = strlen(pfx2); + + plen = (plen1 > plen2) ? plen1 : plen2; + + for (i = 0; i < len; i++) { + if (call1[i] != call2[i]) { + if (min < 0) { + min = i; + max = i; + } + if (max < i) { + max = i; + } + } + } + + // if all existing chars are the same + // AB1CD / AB1CDE -> CDE + // AB1CDE / AB1CD -> 1CD + if (min == -1 && max == -1) { + if (len2 < len1) { // if the new call is shorter + plen--; // include the last char of suffix + } + strncpy(tpartial, call2 + plen, len2 - plen + 1); // the full suffix + tpartial[len2 - plen + 1] = '\0'; + } else { + // if there is only 1 diff, and it's at the end + // AB1CD / AB1CE -> CE + if (min == max && max == len2 - 1) { + min--; // add the previous char too + } + if (len1 == len2) { + // if the mismatch is in the prefix + // AB1CD / AB2CD -> AB2 + if (max <= plen - 1) { + strncpy(tpartial, call2, plen); + tpartial[plen] = '\0'; + } else { + strncpy(tpartial, call2 + min, len2 - min + 1); + tpartial[len2 - min + 1] = '\0'; + } + } else { + strncpy(tpartial, call2 + min, len2 - min + 1); + tpartial[len2 - min + 1] = '\0'; + } + } + strcpy(partial, tpartial); + free(pfx1); + free(pfx2); + + return; +} diff --git a/src/utils.h b/src/utils.h index c89747912..152e0da03 100644 --- a/src/utils.h +++ b/src/utils.h @@ -22,5 +22,6 @@ #define UTILS_H char *find_available(char *filename); +void get_partial_callsign(char *call1, char *call2, char *partial); #endif /* UTILS_H */ diff --git a/tlf.1.in b/tlf.1.in index e1562d072..47aeb3b49 100644 --- a/tlf.1.in +++ b/tlf.1.in @@ -2186,6 +2186,18 @@ and @PACKAGE_NAME@ if is in then the other station's callsign will be sent before \(lqDE\(rq, such as \(lqDL1A DE W1AW\(rq. . +.TP +.B RESENDCALL=\fIFULL\fR | \fIPARTIAL\fR +Sends the partial or the full callsign again in RUN mode, and if the first +recording was wrong. In case of \fIFULL\fR, the whole callsign will send again. +If the value is \fIPARTIAL\fR, then Tlf figures out which part of callsign has +to send. Eg.: if the received call in first case was +.B AB1CD, +but later hi corrects to +.B AB1CB, +then tlf sends +.B CB. +. .SH RULES . The contest rules can be put into separate files. From 66391a7d58d3ee08a0fd872052ace80e511b7d93 Mon Sep 17 00:00:00 2001 From: Ervin Hegedus Date: Tue, 8 Mar 2022 00:46:32 +0100 Subject: [PATCH 02/10] Fix make check issues --- test/data.c | 4 ++++ test/test_adif.c | 2 ++ test/test_cabrillo.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/test/data.c b/test/data.c index a0f5251d7..a63c71fb8 100644 --- a/test/data.c +++ b/test/data.c @@ -414,6 +414,10 @@ char lan_logline[256]; // defined in log_to_disk.c ////////////////// +/* resend call option, can be 0 (do not use), 1 (partial), 2 (full) */ +int resend_call = RESEND_NOT_SET; +char sentcall[20] = ""; // storing the call what already sent + #include NCURSES_EXPORT_VAR(WINDOW *) stdscr = NULL; int wattr_on(WINDOW *win, attr_t attrs, void *opts) { diff --git a/test/test_adif.c b/test/test_adif.c index 9e90b7afc..fb850c57a 100644 --- a/test/test_adif.c +++ b/test/test_adif.c @@ -4,6 +4,7 @@ #include "../src/log_utils.h" #include "../src/globalvars.h" #include "../src/cqww_simulator.h" +#include "../src/getpx.h" // OBJECT ../src/writecabrillo.o // OBJECT ../src/cabrillo_utils.o @@ -12,6 +13,7 @@ // OBJECT ../src/bands.o // OBJECT ../src/sendbuf.o // OBJECT ../src/utils.o +// OBJECT ../src/getpx.o /* test stubs and dummies */ struct linedata_t *parse_logline(char *buffer); diff --git a/test/test_cabrillo.c b/test/test_cabrillo.c index 65055f02d..f8bcb5ac8 100644 --- a/test/test_cabrillo.c +++ b/test/test_cabrillo.c @@ -5,6 +5,7 @@ #include "../src/readcabrillo.h" #include "../src/cqww_simulator.h" #include "../src/log_utils.h" +#include "../src/getpx.h" // OBJECT ../src/cabrillo_utils.o // OBJECT ../src/readcabrillo.o @@ -15,6 +16,7 @@ // OBJECT ../src/sendbuf.o // OBJECT ../src/log_utils.o // OBJECT ../src/utils.o +// OBJECT ../src/getpx.o /* test stubs and dummies */ bool simulator = false; From 461398e9f386f62bc92f4ce2c86811dd495fbe1e Mon Sep 17 00:00:00 2001 From: Ervin Hegedus Date: Sat, 12 Mar 2022 15:36:29 +0100 Subject: [PATCH 03/10] Replace get_partial_callsign() by @zcshok's solution; applied astyle syntax --- src/utils.c | 212 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 157 insertions(+), 55 deletions(-) diff --git a/src/utils.c b/src/utils.c index fdcdc877d..4be2ec53e 100644 --- a/src/utils.c +++ b/src/utils.c @@ -24,6 +24,20 @@ #include "getpx.h" +#define ALT_PREFIX 1 +#define PREFIX 2 +#define AREA 4 +#define SUFFIX 8 +#define ALT_AREA 16 + +typedef struct { + char *alt_prefix; + char *prefix; + char *area; + char *suffix; + char *alt_area; +} call_parts_t; + /* \brief find named file in actual directory or in share * * \returns filename of actual available file or NULL if not found @@ -45,76 +59,164 @@ char *find_available(char *filename) { return path; } +static void free_call_parts(call_parts_t *cp) { + if (cp == NULL) { + return; + } + g_free(cp->alt_prefix); + g_free(cp->prefix); + g_free(cp->area); + g_free(cp->suffix); + g_free(cp->alt_area); + g_free(cp); +} + +// split a call into alt_prefix-prefix-area-suffix-alt_area parts +// returns non-NULL on success with all pointers being also non-NULL +static call_parts_t *split_call(char *call) { + + static const char *PATTERN = "^" + "([A-Z0-9]+/)?" // alt_prefix (optional) + "([A-Z0-9]*?[A-Z])" // prefix + "(\\d+)" // area + "([A-Z]+)" // suffix + "(/[0-9A-Z])?" // alt_area (optional) + "$" + ; + + static GRegex *regex = NULL; + if (regex == NULL) { + regex = g_regex_new(PATTERN, 0, 0, NULL); + } + + call_parts_t *result = NULL; + GMatchInfo *match_info; + g_regex_match(regex, call, 0, &match_info); + + if (g_match_info_matches(match_info)) { + result = g_new(call_parts_t, 1); + result->alt_prefix = g_match_info_fetch(match_info, 1); + if (result->alt_prefix == NULL) { + result->alt_prefix = g_strdup(""); + } + result->prefix = g_match_info_fetch(match_info, 2); + result->area = g_match_info_fetch(match_info, 3); + result->suffix = g_match_info_fetch(match_info, 4); + result->alt_area = g_match_info_fetch(match_info, 5); + if (result->alt_area == NULL) { + result->alt_area = g_strdup(""); + } + + // for an invalid single letter prefix + // shift the first digit of area to it + // example: S 52 -> S5 2 + // valid single letter prefixes: B F G I K M N R W + if (strlen(result->prefix) == 1 + && strchr("BFGIKMNRW", result->prefix[0]) == NULL + && strlen(result->area) >= 2) { + char *p = g_strdup_printf("%s%c", result->prefix, result->area[0]); + char *q = g_strdup(result->area + 1); + g_free(result->prefix); result->prefix = p; + g_free(result->area); result->area = q; + } + + } + + g_match_info_free(match_info); + + return result; +} + /* \brief get a substring from corrected call to repeat it * * \returns a substring based on the sent and corrected callsign */ void get_partial_callsign(char *call1, char *call2, char *partial) { + if (strcmp(call1, call2) == 0) { + strcpy(partial, ""); // calls are equal, nothing to send + return; + } - size_t len1 = strlen(call1), len2 = strlen(call2); - unsigned int len = (len1 < len2) ? len1 : len2; - unsigned int i; - unsigned int plen, plen1, plen2; - int min = -1, max = -1; - char tpartial[20]; - + strcpy(partial, call2); // default: send as-is - tpartial[0] = '\0'; + call_parts_t *cp1 = split_call(call1); + if (cp1 == NULL) { + return; // can't split call1 + } + call_parts_t *cp2 = split_call(call2); + if (cp2 == NULL) { + free_call_parts(cp1); + return; // can't split call2 + } - char *pfx1 = get_wpx_pfx(call1); - char *pfx2 = get_wpx_pfx(call2); + int change = (strcmp(cp1->alt_prefix, cp2->alt_prefix) ? ALT_PREFIX : 0); + change += (strcmp(cp1->prefix, cp2->prefix) ? PREFIX : 0); + change += (strcmp(cp1->area, cp2->area) ? AREA : 0); + change += (strcmp(cp1->suffix, cp2->suffix) ? SUFFIX : 0); + change += (strcmp(cp1->alt_area, cp2->alt_area) ? ALT_AREA : 0); - plen1 = strlen(pfx1); - plen2 = strlen(pfx2); + // handle removal of optional parts + if (change == ALT_AREA && strlen(cp2->alt_area) == 0) { + change = SUFFIX; // treat as suffix change + } + if (change == ALT_PREFIX && strlen(cp2->alt_prefix) == 0) { + change = PREFIX; // treat as prefix change + } - plen = (plen1 > plen2) ? plen1 : plen2; + switch (change) { + case ALT_PREFIX: + strcpy(partial, cp2->alt_prefix); + break; - for (i = 0; i < len; i++) { - if (call1[i] != call2[i]) { - if (min < 0) { - min = i; - max = i; + case PREFIX: + strcpy(partial, cp2->prefix); + if (strlen(partial) == 1) { // if too short, + partial[1] = cp2->area[0]; // add first digit of area + partial[2] = 0; } - if (max < i) { - max = i; - } - } - } + break; - // if all existing chars are the same - // AB1CD / AB1CDE -> CDE - // AB1CDE / AB1CD -> 1CD - if (min == -1 && max == -1) { - if (len2 < len1) { // if the new call is shorter - plen--; // include the last char of suffix - } - strncpy(tpartial, call2 + plen, len2 - plen + 1); // the full suffix - tpartial[len2 - plen + 1] = '\0'; - } else { - // if there is only 1 diff, and it's at the end - // AB1CD / AB1CE -> CE - if (min == max && max == len2 - 1) { - min--; // add the previous char too - } - if (len1 == len2) { - // if the mismatch is in the prefix - // AB1CD / AB2CD -> AB2 - if (max <= plen - 1) { - strncpy(tpartial, call2, plen); - tpartial[plen] = '\0'; + case AREA: + // prepend prefix if area is too short + strcpy(partial, (strlen(cp2->area) == 1 ? cp2->prefix : "")); + strcat(partial, cp2->area); + break; + + case SUFFIX: + // prepend last digit of area if suffix is too short + if (strlen(cp2->suffix) == 1) { + partial[0] = cp2->area[strlen(cp2->area) - 1]; + partial[1] = 0; } else { - strncpy(tpartial, call2 + min, len2 - min + 1); - tpartial[len2 - min + 1] = '\0'; + partial[0] = 0; } - } else { - strncpy(tpartial, call2 + min, len2 - min + 1); - tpartial[len2 - min + 1] = '\0'; - } - } + strcat(partial, cp2->suffix); + break; + + case ALT_AREA: + strcpy(partial, cp2->alt_area); + break; - strcpy(partial, tpartial); - free(pfx1); - free(pfx2); + case ALT_PREFIX + PREFIX: + sprintf(partial, "%s%s", cp2->alt_prefix, cp2->prefix); + break; + + case PREFIX + AREA: + sprintf(partial, "%s%s", cp2->prefix, cp2->area); + break; + + case AREA + SUFFIX: + sprintf(partial, "%s%s", cp2->area, cp2->suffix); + break; + + case SUFFIX + ALT_AREA: + sprintf(partial, "%s%s", cp2->suffix, cp2->alt_area); + break; + + default: // for any other combination send as-is + ; + } - return; + free_call_parts(cp1); + free_call_parts(cp2); } From 44e73c7825afd35064994f42d2ffe6b263b7be9c Mon Sep 17 00:00:00 2001 From: Ervin Hegedus Date: Sat, 12 Mar 2022 15:46:10 +0100 Subject: [PATCH 04/10] Added resend_callsign() to keep the code more readable --- src/logit.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/logit.c b/src/logit.c index 56570bfd6..64dfe91b3 100644 --- a/src/logit.c +++ b/src/logit.c @@ -53,6 +53,7 @@ void refresh_comment(void); void change_mode(void); +void resend_callsign(void); static void log_qso() { log_to_disk(false); @@ -168,25 +169,7 @@ void logit(void) { } else if (defer_store > 1) { if ((cqmode == CQ) && iscontest) { if (cqmode == CQ && resend_call != RESEND_NOT_SET) { - if (strcmp(hiscall, sentcall) != 0) { - char tempmsg[21] = ""; - char partial_call[20]; - switch (resend_call) { - case RESEND_FULL: - sprintf(tempmsg, "%s ", hiscall); - break; - case RESEND_PARTIAL: - get_partial_callsign(sentcall, hiscall, partial_call); - sprintf(tempmsg, "%s ", partial_call); - break; - default: - break; - } - if (tempmsg[0] != '\0') { - sendmessage(tempmsg); - } - } - sentcall[0] = '\0'; + resend_callsign(); } send_standard_message(CQ_TU_MSG); /* send cq return */ set_simulator_state(CALL); @@ -246,3 +229,25 @@ void change_mode(void) { /* and show new mode */ show_header_line(); } + +void resend_callsign() { + if (strcmp(hiscall, sentcall) != 0) { + char tempmsg[21] = ""; + char partial_call[20]; + switch (resend_call) { + case RESEND_FULL: + sprintf(tempmsg, "%s ", hiscall); + break; + case RESEND_PARTIAL: + get_partial_callsign(sentcall, hiscall, partial_call); + sprintf(tempmsg, "%s ", partial_call); + break; + default: + break; + } + if (tempmsg[0] != '\0') { + sendmessage(tempmsg); + } + } + sentcall[0] = '\0'; +} From 4f777a095c72ce1b1c1aa6dfb6613b1c5235b585 Mon Sep 17 00:00:00 2001 From: Ervin Hegedus Date: Sat, 12 Mar 2022 15:50:03 +0100 Subject: [PATCH 05/10] Changed RESENDCALL to RESEND_CALL --- src/parse_logcfg.c | 2 +- src/tlf.h | 2 +- tlf.1.in | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/parse_logcfg.c b/src/parse_logcfg.c index 7a838ef87..c9694f1fe 100644 --- a/src/parse_logcfg.c +++ b/src/parse_logcfg.c @@ -1207,7 +1207,7 @@ static config_t logcfg_configs[] = { {"UNIQUE_CALL_MULTI", NEED_PARAM, cfg_unique_call_multi}, {"DIGI_RIG_MODE", NEED_PARAM, cfg_digi_rig_mode}, {"CABRILLO-(.+)", OPTIONAL_PARAM, cfg_cabrillo_field}, - {"RESENDCALL", NEED_PARAM, cfg_resend_call}, + {"RESEND_CALL", NEED_PARAM, cfg_resend_call}, {NULL} // end marker }; diff --git a/src/tlf.h b/src/tlf.h index e218fbcb7..6c8e9f41b 100644 --- a/src/tlf.h +++ b/src/tlf.h @@ -283,7 +283,7 @@ enum { MARKER_CALLS, /* DOTS & CALLS */ }; -/* Enums for RESENDCALL feature */ +/* Enums for RESEND_CALL feature */ enum { RESEND_NOT_SET, /* Resend feature not set */ RESEND_PARTIAL, /* Resend partial hiscall */ diff --git a/tlf.1.in b/tlf.1.in index 47aeb3b49..3aa4154d5 100644 --- a/tlf.1.in +++ b/tlf.1.in @@ -2187,7 +2187,7 @@ then the other station's callsign will be sent before \(lqDE\(rq, such as \(lqDL1A DE W1AW\(rq. . .TP -.B RESENDCALL=\fIFULL\fR | \fIPARTIAL\fR +.B RESEND_CALL=\fIFULL\fR | \fIPARTIAL\fR Sends the partial or the full callsign again in RUN mode, and if the first recording was wrong. In case of \fIFULL\fR, the whole callsign will send again. If the value is \fIPARTIAL\fR, then Tlf figures out which part of callsign has From c7cc01f03a34ee2b96b361003c64f69f2de881dc Mon Sep 17 00:00:00 2001 From: zcsahok Date: Sat, 12 Mar 2022 20:08:56 +0000 Subject: [PATCH 06/10] minor RESEND_CALL doc update --- src/parse_logcfg.c | 2 +- tlf.1.in | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/parse_logcfg.c b/src/parse_logcfg.c index c9694f1fe..89affdfa1 100644 --- a/src/parse_logcfg.c +++ b/src/parse_logcfg.c @@ -1035,7 +1035,7 @@ static int cfg_resend_call(const cfg_arg_t arg) { resend_call = RESEND_FULL; } else { g_free(str); - error_details = g_strdup("must be PARTIAL or FULL"); + error_details = g_strdup("must be FULL or PARTIAL"); return PARSE_WRONG_PARAMETER; } diff --git a/tlf.1.in b/tlf.1.in index 3aa4154d5..7448ed43d 100644 --- a/tlf.1.in +++ b/tlf.1.in @@ -2188,15 +2188,17 @@ then the other station's callsign will be sent before \(lqDE\(rq, such as . .TP .B RESEND_CALL=\fIFULL\fR | \fIPARTIAL\fR -Sends the partial or the full callsign again in RUN mode, and if the first -recording was wrong. In case of \fIFULL\fR, the whole callsign will send again. -If the value is \fIPARTIAL\fR, then Tlf figures out which part of callsign has -to send. Eg.: if the received call in first case was +Sends the full or partial callsign again at the end of the QSO +in RUN mode if the call of the other station was corrected. +In case of \fIFULL\fR the whole callsign will be sent again. +If the value is \fIPARTIAL\fR, then TLF figures out which part of callsign +has to be sent. Eg.: if the received call was .B AB1CD, -but later hi corrects to +but later it is corrected to .B AB1CB, -then tlf sends +then .B CB. +is sent. . .SH RULES . From 8220d5af73dbddb7080a2b767527e0f3fb7ef1aa Mon Sep 17 00:00:00 2001 From: zcsahok Date: Sat, 12 Mar 2022 20:09:58 +0000 Subject: [PATCH 07/10] minor resend_callsign upd --- src/logit.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/logit.c b/src/logit.c index 64dfe91b3..7be9920df 100644 --- a/src/logit.c +++ b/src/logit.c @@ -231,22 +231,21 @@ void change_mode(void) { } void resend_callsign() { - if (strcmp(hiscall, sentcall) != 0) { - char tempmsg[21] = ""; - char partial_call[20]; + if (sentcall[0] != 0 && strcmp(hiscall, sentcall) != 0) { + char partial_call[21] = ""; switch (resend_call) { case RESEND_FULL: - sprintf(tempmsg, "%s ", hiscall); + strcpy(partial_call, hiscall); break; case RESEND_PARTIAL: get_partial_callsign(sentcall, hiscall, partial_call); - sprintf(tempmsg, "%s ", partial_call); break; default: break; } - if (tempmsg[0] != '\0') { - sendmessage(tempmsg); + if (partial_call[0] != '\0') { + strcat(partial_call, " "); // append a space + sendmessage(partial_call); } } sentcall[0] = '\0'; From 1fbdeddbb01cbf9cf541ed023736e3c1099be327 Mon Sep 17 00:00:00 2001 From: zcsahok Date: Sat, 12 Mar 2022 20:25:58 +0000 Subject: [PATCH 08/10] minor resend_callsign upd2 --- src/logit.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/logit.c b/src/logit.c index 7be9920df..8785dc829 100644 --- a/src/logit.c +++ b/src/logit.c @@ -167,10 +167,8 @@ void logit(void) { defer_store++; callreturn = 0; } else if (defer_store > 1) { - if ((cqmode == CQ) && iscontest) { - if (cqmode == CQ && resend_call != RESEND_NOT_SET) { - resend_callsign(); - } + if (cqmode == CQ && iscontest) { + resend_callsign(); send_standard_message(CQ_TU_MSG); /* send cq return */ set_simulator_state(CALL); From 971a01d0d27f42b866038dadcc1900ed3a8241a9 Mon Sep 17 00:00:00 2001 From: Ervin Hegedus Date: Sun, 13 Mar 2022 01:15:43 +0100 Subject: [PATCH 09/10] Remove unnecessary headers and objects from test; move initial set of RESEND_CALL to init_variables() --- src/main.c | 3 ++- test/data.c | 2 +- test/test_adif.c | 2 -- test/test_cabrillo.c | 2 -- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main.c b/src/main.c index cf5bf105e..a7c9f4a31 100644 --- a/src/main.c +++ b/src/main.c @@ -442,7 +442,7 @@ static const struct argp_option options[] = { }; /* resend call option, can be 0 (do not use), 1 (partial), 2 (full) */ -int resend_call = RESEND_NOT_SET; +int resend_call; char sentcall[20] = ""; // storing the call what already sent /* parse a single option */ @@ -631,6 +631,7 @@ static void init_variables() { tune_seconds = 6; /* tune up for 6 s */ ctcomp = false; + resend_call = RESEND_NOT_SET; for (int i = 0; i < 25; i++) { FREE_DYNAMIC_STRING(digi_message[i]); diff --git a/test/data.c b/test/data.c index a63c71fb8..e009257ae 100644 --- a/test/data.c +++ b/test/data.c @@ -415,7 +415,7 @@ char lan_logline[256]; // defined in log_to_disk.c ////////////////// /* resend call option, can be 0 (do not use), 1 (partial), 2 (full) */ -int resend_call = RESEND_NOT_SET; +int resend_call; char sentcall[20] = ""; // storing the call what already sent #include diff --git a/test/test_adif.c b/test/test_adif.c index fb850c57a..9e90b7afc 100644 --- a/test/test_adif.c +++ b/test/test_adif.c @@ -4,7 +4,6 @@ #include "../src/log_utils.h" #include "../src/globalvars.h" #include "../src/cqww_simulator.h" -#include "../src/getpx.h" // OBJECT ../src/writecabrillo.o // OBJECT ../src/cabrillo_utils.o @@ -13,7 +12,6 @@ // OBJECT ../src/bands.o // OBJECT ../src/sendbuf.o // OBJECT ../src/utils.o -// OBJECT ../src/getpx.o /* test stubs and dummies */ struct linedata_t *parse_logline(char *buffer); diff --git a/test/test_cabrillo.c b/test/test_cabrillo.c index f8bcb5ac8..65055f02d 100644 --- a/test/test_cabrillo.c +++ b/test/test_cabrillo.c @@ -5,7 +5,6 @@ #include "../src/readcabrillo.h" #include "../src/cqww_simulator.h" #include "../src/log_utils.h" -#include "../src/getpx.h" // OBJECT ../src/cabrillo_utils.o // OBJECT ../src/readcabrillo.o @@ -16,7 +15,6 @@ // OBJECT ../src/sendbuf.o // OBJECT ../src/log_utils.o // OBJECT ../src/utils.o -// OBJECT ../src/getpx.o /* test stubs and dummies */ bool simulator = false; From 079d6cd5c96316e09969cb1ef865fbb2c8b72a07 Mon Sep 17 00:00:00 2001 From: zcsahok Date: Sun, 13 Mar 2022 08:04:41 +0000 Subject: [PATCH 10/10] add test for get_partial_callsign --- test/test_utils.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 test/test_utils.c diff --git a/test/test_utils.c b/test/test_utils.c new file mode 100644 index 000000000..ad0bed459 --- /dev/null +++ b/test/test_utils.c @@ -0,0 +1,68 @@ +#include "test.h" + +#include "../src/utils.h" + +// OBJECT ../src/utils.o + +typedef struct { + char *call1; + char *call2; + char *expected; +} partial_call_t; + +static partial_call_t tests[] = { + {"WB6A", "W6BA", "W6BA"}, + {"HA2OH", "HA2OS", "OS"}, + {"HA2MS", "HA2OS", "OS"}, + {"HA2MH", "HA2OS", "OS"}, + {"HA2MH", "S52OS", "S52OS"}, + {"S2MH", "S52OS", "S52OS"}, + {"S2MH", "S52MH", "S5"}, + {"OK2FHI", "OK1FHI", "OK1"}, + {"OK1FH", "OK1FHI", "FHI"}, + {"OK2FH", "OK1FHI", "1FHI"}, + {"WB6AB", "WB6A", "6A"}, + {"HG5N", "HA5N", "HA"}, + {"HG5N", "HG55N", "55"}, + {"HG5N", "HG6N", "HG6"}, + {"HG5N", "HG5D", "5D"}, + {"PA1234X", "PA1834X", "1834"}, + {"PA1234X", "PA1834K", "1834K"}, + {"PA1234X", "PA1234K", "4K"}, + {"PA1234X", "RA1234X", "RA"}, + {"F1234X", "R1234X", "R1"}, + {"F1234X", "R1234C", "R1234C"}, + {"K1A", "K1W", "1W"}, + {"K1A", "W1A", "W1"}, + {"K1A", "K2A", "K2"}, + {"DL1ABC", "DL1ADC", "ADC"}, + {"R1ABC/2", "R1ABC/3", "/3"}, + {"R1ABC/2", "R1ADC/2", "ADC"}, + {"R1ABC/2", "R4ADC/2", "4ADC"}, + {"R1ABC/2", "R1ADC/3", "ADC/3"}, + {"R1A/2", "R1W/2", "1W"}, + {"EA8/HB9ABC", "EA8/HB9ANC", "ANC"}, + {"EA8/HB9ABC", "EA6/HB9ABC", "EA6/"}, + {"EA8/HB9ABC", "EA6/HB9ANC", "EA6/HB9ANC"}, + {"EA8/DL1ABC", "EA8/DK1ABC", "DK"}, + {"EA8/DL1ABC", "EA6/DK1ABC", "EA6/DK"}, + {"G/DF1ABC", "F/DF1ABC", "F/"}, + {"LA/DF1ABC", "PA/DF1ABC", "PA/"}, + {"HA5ABC/P", "HA5ABC", "ABC"}, + {"HA5ABC", "HA5ABC/P", "/P"}, + {"HB9/OK1ABC", "OK1ABC", "OK"}, + {"OK1ABC", "HB9/OK1ABC", "HB9/"}, + {"HA5ABE", "HA5AB", "AB"}, + {"HA5ABE", "HW5AB", "HW5AB"}, +}; + + +void test_get_partial_callsign(void **state) { + char partial[20]; + for (int i = 0; i < sizeof(tests) / sizeof(tests[0]); ++i) { + printf("%s -> %s\n", tests[i].call1, tests[i].call2); + get_partial_callsign(tests[i].call1, tests[i].call2, partial); + assert_string_equal(tests[i].expected, partial); + } +} +