Skip to content

Commit 7f4e7ef

Browse files
committed
Add --cabrillo-round-freq to round fractional frequencies down
1 parent f465c0d commit 7f4e7ef

3 files changed

Lines changed: 25 additions & 10 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,15 @@ input.
1414

1515
## [Unreleased]
1616

17-
Nothing yet
17+
### Added
18+
19+
* `--cabrillo-round-freq` flag rounds HF frequency down to a whole kilohertz
20+
value. The ncjweb.com Cabrillo parser does not accept fractional kHz values
21+
like `14012.34`.
22+
23+
### Fixed
24+
25+
* Cabrillo: Include the field name when an expected field has an error.
1826

1927

2028
## [0.1.21] - 2025-09-17

adif/cabrillo.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ type CabrilloIO struct {
4242
MinReportedOfftime time.Duration
4343
Categories map[string]string
4444
MyExchange, TheirExchange, ExtraFields CabrilloFieldList
45-
TabDelimiter bool
45+
TabDelimiter, RoundKHz bool
4646
}
4747

4848
func NewCabrilloIO() *CabrilloIO {
@@ -380,6 +380,7 @@ func (o *CabrilloIO) toConfig() cabrilloConfig {
380380
}
381381
c := cabrilloConfig{
382382
useTabs: o.TabDelimiter,
383+
roundKHz: o.RoundKHz,
383384
coreLen: len(cabCoreFields),
384385
myLen: len(o.MyExchange) + 1,
385386
theirLen: len(o.TheirExchange) + 1,
@@ -394,7 +395,7 @@ func (o *CabrilloIO) toConfig() cabrilloConfig {
394395
return c
395396
}
396397

397-
func mhzToKhz(mhz string) string {
398+
func mhzToKhz(mhz string, round bool) string {
398399
pieces := strings.Split(mhz, ".")
399400
if len(pieces) == 1 {
400401
return mhz + "000" // 14 MHz -> 14000 kHz
@@ -409,7 +410,11 @@ func mhzToKhz(mhz string) string {
409410
case 3:
410411
return pieces[0] + pieces[1]
411412
default:
412-
return pieces[0] + pieces[1][0:3] + "." + pieces[1][3:]
413+
khz := pieces[0] + pieces[1][0:3]
414+
if round {
415+
return khz
416+
}
417+
return khz + "." + pieces[1][3:]
413418
}
414419
}
415420

@@ -615,7 +620,7 @@ func parseCabrilloField(v string) (CabrilloField, error) {
615620
return CabrilloField{Header: strings.TrimSuffix(g[1], ":"), TryFields: try, AllowEmpty: g[3] == "?", Default: def}, nil
616621
}
617622

618-
func (c *CabrilloField) fromADIF(r *Record) (string, error) {
623+
func (c *CabrilloField) fromADIF(r *Record, conf cabrilloConfig) (string, error) {
619624
var v string
620625
for _, t := range c.TryFields {
621626
if v != "" {
@@ -630,13 +635,13 @@ func (c *CabrilloField) fromADIF(r *Record) (string, error) {
630635
case "QSO_DATE", "QSO_DATE_OFF":
631636
d, err := r.ParseDate(t)
632637
if err != nil {
633-
return "", err
638+
return "", fmt.Errorf("%s: %w", t, err)
634639
}
635640
v = d.Format("2006-01-02")
636641
case "TIME_ON", "TIME_OFF":
637642
d, err := r.ParseTime(t)
638643
if err != nil {
639-
return "", err
644+
return "", fmt.Errorf("%s: %w", t, err)
640645
}
641646
v = d.Format("1504")
642647
case "FREQ":
@@ -651,7 +656,7 @@ func (c *CabrilloField) fromADIF(r *Record) (string, error) {
651656
} else {
652657
f, _ := r.Get(t) // ParseFloat already determined it's set
653658
// string-to-string to avoid floating point precision issues
654-
v = mhzToKhz(f.Value)
659+
v = mhzToKhz(f.Value, conf.roundKHz)
655660
}
656661
case "BAND":
657662
if f, ok := r.Get(t); ok && f.Value != "" {
@@ -799,7 +804,7 @@ type cabrilloConfig struct {
799804
// core, my, their, extra
800805
fields CabrilloFieldList
801806
coreLen, myLen, theirLen, extraLen int
802-
useTabs bool
807+
useTabs, roundKHz bool
803808
}
804809

805810
func (c cabrilloConfig) toADIF(qso string) (*Record, error) {
@@ -828,7 +833,7 @@ func (c cabrilloConfig) toADIF(qso string) (*Record, error) {
828833
func (c cabrilloConfig) toCabrillo(r *Record) (cabrilloRecord, error) {
829834
cr := cabrilloRecord{fields: make([]string, len(c.fields))}
830835
for i, f := range c.fields {
831-
v, err := f.fromADIF(r)
836+
v, err := f.fromADIF(r, c)
832837
if err != nil {
833838
return cabrilloRecord{}, err
834839
}

adifmt/formats.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ func (c cabrilloConfig) AddFlags(fs *flag.FlagSet) {
105105
c.io.CreatedBy = "ADIF Multitool " + version
106106
fs.BoolVar(&c.io.TabDelimiter, "cabrillo-delimiter-tab", false,
107107
"Use tabs rather than space-aligned columns")
108+
fs.BoolVar(&c.io.RoundKHz, "cabrillo-round-freq", false,
109+
"Round frequency down to whole kHz")
108110
fs.IntVar(&c.io.LowPowerMax, "cabrillo-max-power-low", c.io.LowPowerMax,
109111
"Highest allowed power in `watts` considered LOW power by the contest")
110112
fs.IntVar(&c.io.QRPPowerMax, "cabrillo-max-power-qrp", c.io.QRPPowerMax,

0 commit comments

Comments
 (0)