Added SOTA, WWFF and QSLmsg parsing

pull/2/head
Jean-Marc MEESSEN 4 years ago
parent 9b4b9a7dda
commit 8443c27b18

@ -24,7 +24,7 @@ import (
var validCallRegexp = regexp.MustCompile(`[\d]{0,1}[A-Z]{1,2}\d([A-Z]{1,4}|\d{3,3}|\d{1,3}[A-Z])[A-Z]{0,5}`) var validCallRegexp = regexp.MustCompile(`[\d]{0,1}[A-Z]{1,2}\d([A-Z]{1,4}|\d{3,3}|\d{1,3}[A-Z])[A-Z]{0,5}`)
var validPrefixRegexp = regexp.MustCompile(`\A\d?[a-zA-Z]{1,2}$`) var validPrefixRegexp = regexp.MustCompile(`\A\d?[a-zA-Z]{1,2}$`)
// ValidateCall veriffies whether the supplied string is a valid callsign. // ValidateCall verifies whether the supplied string is a valid callsign.
// prefix and suffix are not checked for validity // prefix and suffix are not checked for validity
// If it is not valid, the supicious string is prefixed with a * and an erroMsg is genrated. // If it is not valid, the supicious string is prefixed with a * and an erroMsg is genrated.
func ValidateCall(sign string) (call, errorMsg string) { func ValidateCall(sign string) (call, errorMsg string) {

@ -80,14 +80,17 @@ func loadFile() {
regexpEndMultiLineComment, _ := regexp.Compile("}$") regexpEndMultiLineComment, _ := regexp.Compile("}$")
regexpHeaderMyCall, _ := regexp.Compile("(?i)^mycall ") regexpHeaderMyCall, _ := regexp.Compile("(?i)^mycall ")
regexpHeaderOperator, _ := regexp.Compile("(?i)^operator ") regexpHeaderOperator, _ := regexp.Compile("(?i)^operator ")
// regexpHeaderMyWwff, _ := regexp.Compile("(?i)^mywwff ") regexpHeaderMyWwff, _ := regexp.Compile("(?i)^mywwff ")
// regexpHeaderMySota, _ := regexp.Compile("(?i)^mysota ") regexpHeaderMySota, _ := regexp.Compile("(?i)^mysota ")
// regexpHeaderQslMsg, _ := regexp.Compile("(?i)^qslmsg ") regexpHeaderQslMsg, _ := regexp.Compile("(?i)^qslmsg ")
// regexpHeaderNickname, _ := regexp.Compile("(?i)^nickname ") // regexpHeaderNickname, _ := regexp.Compile("(?i)^nickname ")
// regexpHeaderDate, _ := regexp.Compile("(?i)^date ") // regexpHeaderDate, _ := regexp.Compile("(?i)^date ")
headerMyCall := "" headerMyCall := ""
headerOperator := "" headerOperator := ""
headerMyWWFF := ""
headerMySOTA := ""
//headerQslMsg := ""
lineCount := 0 lineCount := 0
var isInMultiLine = false var isInMultiLine = false
@ -133,6 +136,7 @@ func loadFile() {
// ** Process the Header block // ** Process the Header block
// **** // ****
//My Call
if(regexpHeaderMyCall.MatchString(eachline)) { if(regexpHeaderMyCall.MatchString(eachline)) {
errorMsg := "" errorMsg := ""
myCallList := regexpHeaderMyCall.Split(eachline,-1) myCallList := regexpHeaderMyCall.Split(eachline,-1)
@ -142,12 +146,12 @@ func loadFile() {
if(len(errorMsg) != 0) { if(len(errorMsg) != 0) {
errorLog = append(errorLog, fmt.Sprintf("Invalid myCall at line %d: %s (%s)",lineCount, myCallList[1], errorMsg)) errorLog = append(errorLog, fmt.Sprintf("Invalid myCall at line %d: %s (%s)",lineCount, myCallList[1], errorMsg))
} }
} else {
errorLog = append(errorLog, fmt.Sprintf("Undefined myCall at line %d",lineCount))
} }
//If there is no data after the marker, we just skip the data.
continue continue
} }
//Operator
if(regexpHeaderOperator.MatchString(eachline)) { if(regexpHeaderOperator.MatchString(eachline)) {
errorMsg := "" errorMsg := ""
myOperatorList := regexpHeaderOperator.Split(eachline,-1) myOperatorList := regexpHeaderOperator.Split(eachline,-1)
@ -157,11 +161,51 @@ func loadFile() {
if(len(errorMsg) != 0) { if(len(errorMsg) != 0) {
errorLog = append(errorLog, fmt.Sprintf("Invalid Operator at line %d: %s (%s)",lineCount, myOperatorList[1], errorMsg)) errorLog = append(errorLog, fmt.Sprintf("Invalid Operator at line %d: %s (%s)",lineCount, myOperatorList[1], errorMsg))
} }
} else {
errorLog = append(errorLog, fmt.Sprintf("Undefined Operator at line %d",lineCount))
} }
//If there is no data after the marker, we just skip the data.
continue continue
} }
// My WWFF
if(regexpHeaderMyWwff.MatchString(eachline)) {
errorMsg := ""
myWwffList := regexpHeaderMyWwff.Split(eachline,-1)
if(len(myWwffList[1]) > 0) {
headerMyWWFF, errorMsg = ValidateWwff(myWwffList[1])
cleanedInput = append(cleanedInput, fmt.Sprintf("My WWFF: %s", headerMyWWFF))
if(len(errorMsg) != 0) {
errorLog = append(errorLog, fmt.Sprintf("Invalid \"My WWFF\" at line %d: %s (%s)",lineCount, myWwffList[1], errorMsg))
}
}
//If there is no data after the marker, we just skip the data.
continue
}
//My Sota
if(regexpHeaderMySota.MatchString(eachline)) {
errorMsg := ""
mySotaList := regexpHeaderMySota.Split(eachline,-1)
if(len(mySotaList[1]) > 0) {
headerMySOTA, errorMsg = ValidateSota(mySotaList[1])
cleanedInput = append(cleanedInput, fmt.Sprintf("My Sota: %s", headerMySOTA))
if(len(errorMsg) != 0) {
errorLog = append(errorLog, fmt.Sprintf("Invalid \"My SOTA\" at line %d: %s (%s)",lineCount, mySotaList[1], errorMsg))
}
}
//If there is no data after the marker, we just skip the data.
continue
}
//QSL Message
if(regexpHeaderQslMsg.MatchString(eachline)) {
myQslMsgList := regexpHeaderQslMsg.Split(eachline,-1)
if(len(myQslMsgList[1]) > 0) {
cleanedInput = append(cleanedInput, fmt.Sprintf("QSL Message: %s", myQslMsgList[1]))
}
//If there is no data after the marker, we just skip the data.
continue
}
// **** // ****
// ** Process the data block // ** Process the data block
// **** // ****
@ -169,6 +213,9 @@ func loadFile() {
} }
//*****
//** display results
//*****
for _, cleanedInputLine := range cleanedInput { for _, cleanedInputLine := range cleanedInput {
fmt.Println(cleanedInputLine) fmt.Println(cleanedInputLine)
} }

@ -0,0 +1,35 @@
package cmd
/*
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import (
"regexp"
"strings"
)
var validSotaRegexp = regexp.MustCompile(`^[0-9A-Z]{1,3}/[A-Z]{2}-[\d]{3}$`)
// ValidateSota verifies whether the supplied string is a valid SOTA reference.
// The syntax is: AA/NN-CCC: Association/Name-3-digit numeric Code (e.g. G/CE-001).
func ValidateSota(inputStr string) (ref, errorMsg string) {
inputStr = strings.ToUpper(strings.TrimSpace(inputStr))
wrongInputStr := "*" + inputStr
if validSotaRegexp.MatchString(inputStr) {
return inputStr, ""
}
return wrongInputStr, "Invalid SOTA reference"
}

@ -0,0 +1,82 @@
package cmd
import "testing"
func TestValidateSota(t *testing.T) {
type args struct {
inputStr string
}
tests := []struct {
name string
args args
wantRef string
wantErrorMsg string
}{
{
"Good ref (simple)",
args{ inputStr: "on/ON-001", },
"ON/ON-001", "",
},
{
"Good ref (single digit prefix)",
args{ inputStr: "g/ON-001", },
"G/ON-001", "",
},
{
"Good ref (numerical prefix)",
args{ inputStr: "4x/ON-001", },
"4X/ON-001", "",
},
{
"Good ref (american style)",
args{ inputStr: "w4z/ON-001", },
"W4Z/ON-001", "",
},
{
"Bad ref (long prefix)",
args{ inputStr: "xxxx/ON-001", },
"*XXXX/ON-001", "Invalid SOTA reference",
},
{
"Bad ref (missing slash)",
args{ inputStr: "on ON-001", },
"*ON ON-001", "Invalid SOTA reference",
},
{
"Bad ref (numerical region)",
args{ inputStr: "on/9N-001", },
"*ON/9N-001", "Invalid SOTA reference",
},
{
"Bad ref (too long region)",
args{ inputStr: "on/ONA-001", },
"*ON/ONA-001", "Invalid SOTA reference",
},
{
"Bad ref (no dash)",
args{ inputStr: "on/ON/001", },
"*ON/ON/001", "Invalid SOTA reference",
},
{
"Bad ref (number too short)",
args{ inputStr: "on/ON-01", },
"*ON/ON-01", "Invalid SOTA reference",
},
{
"Bad ref (Number too long)",
args{ inputStr: "on/ON-9001", },
"*ON/ON-9001", "Invalid SOTA reference",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotRef, gotErrorMsg := ValidateSota(tt.args.inputStr)
if gotRef != tt.wantRef {
t.Errorf("ValidateSota() gotRef = %v, want %v", gotRef, tt.wantRef)
}
if gotErrorMsg != tt.wantErrorMsg {
t.Errorf("ValidateSota() gotErrorMsg = %v, want %v", gotErrorMsg, tt.wantErrorMsg)
}
})
}
}

@ -0,0 +1,35 @@
package cmd
/*
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import (
"regexp"
"strings"
)
var validWwffRegexp = regexp.MustCompile(`^[\d]{0,1}[A-Z]{1,2}FF-[\d]{4}$`)
// ValidateWwff verifies whether the supplied string is a valid WWFF reference.
// The syntax is: AAFF-CCCC: AA = national prefix, CCCC = 4-digit numeric code (e.g. ONFF-0001).
func ValidateWwff(inputStr string) (ref, errorMsg string) {
inputStr = strings.ToUpper(strings.TrimSpace(inputStr))
wrongInputStr := "*" + inputStr
if validWwffRegexp.MatchString(inputStr) {
return inputStr, ""
}
return wrongInputStr, "Invalid WWFF reference"
}

@ -0,0 +1,43 @@
package cmd
import "testing"
func TestValidateWwff(t *testing.T) {
type args struct {
inputStr string
}
tests := []struct {
name string
args args
wantRef string
wantErrorMsg string
}{
{
"Good call (simple)",
args{ inputStr: "onff-0258", },
"ONFF-0258", "",
},
{
"Good call (simple)",
args{ inputStr: "fff-0258", },
"FFF-0258", "",
},
{
"Good call (simple)",
args{ inputStr: "4xff-0258", },
"4XFF-0258", "",
},
//TODO: add the invalid cases
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotRef, gotErrorMsg := ValidateWwff(tt.args.inputStr)
if gotRef != tt.wantRef {
t.Errorf("ValidateWwff() gotRef = %v, want %v", gotRef, tt.wantRef)
}
if gotErrorMsg != tt.wantErrorMsg {
t.Errorf("ValidateWwff() gotErrorMsg = %v, want %v", gotErrorMsg, tt.wantErrorMsg)
}
})
}
}
Loading…
Cancel
Save