mirror of
https://github.com/on4kjm/FLEcli.git
synced 2025-01-31 06:51:02 +01:00
Reformat the sources with go fmt
This commit is contained in:
parent
590988f3ad
commit
ab925ad2dd
8 changed files with 311 additions and 322 deletions
|
@ -1,4 +1,5 @@
|
|||
package cmd
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
|
@ -24,8 +25,8 @@ type BraketType int
|
|||
|
||||
//Enumeration of the valid Bracket Types
|
||||
const (
|
||||
COMMENT BraketType = iota
|
||||
QSL
|
||||
COMMENT BraketType = iota
|
||||
QSL
|
||||
)
|
||||
|
||||
func getBraketedData(inputLine string, braketType BraketType) (braketedData, cleanedLine string) {
|
||||
|
@ -37,26 +38,26 @@ func getBraketedData(inputLine string, braketType BraketType) (braketedData, cle
|
|||
if braketType == COMMENT {
|
||||
a = "<"
|
||||
b = ">"
|
||||
}
|
||||
}
|
||||
if braketType == QSL {
|
||||
a = "["
|
||||
b = "]"
|
||||
}
|
||||
}
|
||||
|
||||
posFirst := strings.Index(inputLine, a)
|
||||
if posFirst == -1 {
|
||||
return "",inputLine
|
||||
}
|
||||
posLast := strings.Index(inputLine, b)
|
||||
if posLast == -1 {
|
||||
return "",inputLine
|
||||
}
|
||||
posFirstAdjusted := posFirst + 1
|
||||
if posFirstAdjusted > posLast {
|
||||
return "",inputLine
|
||||
posFirst := strings.Index(inputLine, a)
|
||||
if posFirst == -1 {
|
||||
return "", inputLine
|
||||
}
|
||||
posLast := strings.Index(inputLine, b)
|
||||
if posLast == -1 {
|
||||
return "", inputLine
|
||||
}
|
||||
posFirstAdjusted := posFirst + 1
|
||||
if posFirstAdjusted > posLast {
|
||||
return "", inputLine
|
||||
}
|
||||
|
||||
braketedData = inputLine[posFirstAdjusted:posLast]
|
||||
cleanedLine = strings.Replace(inputLine, a + braketedData + b, "",1)
|
||||
return braketedData, cleanedLine
|
||||
}
|
||||
cleanedLine = strings.Replace(inputLine, a+braketedData+b, "", 1)
|
||||
return braketedData, cleanedLine
|
||||
}
|
||||
|
|
|
@ -14,45 +14,45 @@ func Test_getBraketedData(t *testing.T) {
|
|||
wantCleanedLine string
|
||||
}{
|
||||
{
|
||||
"Happy case: comment",
|
||||
args{ inputLine: "aaaa <bracketed text> bbbbb", braketType: COMMENT},
|
||||
"bracketed text",
|
||||
"Happy case: comment",
|
||||
args{inputLine: "aaaa <bracketed text> bbbbb", braketType: COMMENT},
|
||||
"bracketed text",
|
||||
"aaaa bbbbb",
|
||||
},
|
||||
{
|
||||
"Happy case: QSL",
|
||||
args{ inputLine: "aaaa [bracketed text] bbbbb", braketType: QSL},
|
||||
"bracketed text",
|
||||
"Happy case: QSL",
|
||||
args{inputLine: "aaaa [bracketed text] bbbbb", braketType: QSL},
|
||||
"bracketed text",
|
||||
"aaaa bbbbb",
|
||||
},
|
||||
{
|
||||
"Happy case: nothing",
|
||||
args{ inputLine: "aaaa bbbbb cccccc", braketType: QSL},
|
||||
"",
|
||||
"Happy case: nothing",
|
||||
args{inputLine: "aaaa bbbbb cccccc", braketType: QSL},
|
||||
"",
|
||||
"aaaa bbbbb cccccc",
|
||||
},
|
||||
{
|
||||
"Empty brackets",
|
||||
args{ inputLine: "aaaa <> bbbbb", braketType: COMMENT},
|
||||
"",
|
||||
"Empty brackets",
|
||||
args{inputLine: "aaaa <> bbbbb", braketType: COMMENT},
|
||||
"",
|
||||
"aaaa bbbbb",
|
||||
},
|
||||
{
|
||||
"Brackets at right",
|
||||
args{ inputLine: "aaaa bbbbb <bracketed text>", braketType: COMMENT},
|
||||
"bracketed text",
|
||||
"Brackets at right",
|
||||
args{inputLine: "aaaa bbbbb <bracketed text>", braketType: COMMENT},
|
||||
"bracketed text",
|
||||
"aaaa bbbbb ",
|
||||
},
|
||||
{
|
||||
"concatenated",
|
||||
args{ inputLine: "aaaa<bracketed text>bbbbb", braketType: COMMENT},
|
||||
"bracketed text",
|
||||
"concatenated",
|
||||
args{inputLine: "aaaa<bracketed text>bbbbb", braketType: COMMENT},
|
||||
"bracketed text",
|
||||
"aaaabbbbb",
|
||||
},
|
||||
{
|
||||
"duplicated",
|
||||
args{ inputLine: "aaaa <bracketed text> bbbbb < double > cccc", braketType: COMMENT},
|
||||
"bracketed text",
|
||||
"duplicated",
|
||||
args{inputLine: "aaaa <bracketed text> bbbbb < double > cccc", braketType: COMMENT},
|
||||
"bracketed text",
|
||||
"aaaa bbbbb < double > cccc",
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
package cmd
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
|
@ -19,7 +20,7 @@ import (
|
|||
)
|
||||
|
||||
// SprintLogRecord outputs the content of a logline
|
||||
func SprintLogRecord(logLine LogLine) (output string){
|
||||
func SprintLogRecord(logLine LogLine) (output string) {
|
||||
output = ""
|
||||
output = output + "Date " + logLine.Date + "\n"
|
||||
output = output + "MyCall " + logLine.MyCall + "\n"
|
||||
|
@ -49,10 +50,10 @@ func SprintLogRecord(logLine LogLine) (output string){
|
|||
}
|
||||
|
||||
// SprintHeaderValues displays the header values
|
||||
func SprintHeaderValues(logLine LogLine) (output string){
|
||||
func SprintHeaderValues(logLine LogLine) (output string) {
|
||||
output = ""
|
||||
|
||||
output = output + "MyCall " + logLine.MyCall
|
||||
output = output + "MyCall " + logLine.MyCall
|
||||
if logLine.Operator != "" {
|
||||
output = output + " (" + logLine.Operator + ")"
|
||||
}
|
||||
|
@ -66,21 +67,21 @@ func SprintHeaderValues(logLine LogLine) (output string){
|
|||
output = output + "MySOTA " + logLine.MySOTA + "\n"
|
||||
}
|
||||
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
// Date, Time, band, mode, call, report sent, report rcvd, Notes
|
||||
var logLineFormat = "%-10s %-4s %-4s %-4s %-10s %-4s %-4s %s \n"
|
||||
|
||||
// SprintColumnTitles displays the column titles for a log line
|
||||
func SprintColumnTitles(logLine LogLine) (output string){
|
||||
func SprintColumnTitles(logLine LogLine) (output string) {
|
||||
output = fmt.Sprintf(logLineFormat, "Date", "Time", "Band", "Mode", "Call", "Sent", "Rcvd", "Notes")
|
||||
output = output + fmt.Sprintf(logLineFormat, "----", "----", "----", "----", "----", "----", "----", "----")
|
||||
return output
|
||||
}
|
||||
|
||||
// SprintLogInColumn displays the logLine in column mode
|
||||
func SprintLogInColumn(logLine LogLine) (output string){
|
||||
func SprintLogInColumn(logLine LogLine) (output string) {
|
||||
notes := ""
|
||||
if logLine.Frequency != "" {
|
||||
notes = notes + "QRG: " + logLine.Frequency + " "
|
||||
|
@ -107,4 +108,4 @@ func SprintLogInColumn(logLine LogLine) (output string){
|
|||
output = fmt.Sprintf(logLineFormat, logLine.Date, logLine.Time, logLine.Band, logLine.Mode, logLine.Call, logLine.RSTsent, logLine.RSTrcvd, notes)
|
||||
|
||||
return output
|
||||
}
|
||||
}
|
||||
|
|
124
cmd/load.go
124
cmd/load.go
|
@ -1,4 +1,5 @@
|
|||
package cmd
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
|
@ -16,9 +17,9 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
"bufio"
|
||||
"log"
|
||||
"os"
|
||||
"regexp"
|
||||
|
@ -29,12 +30,12 @@ import (
|
|||
var loadCmd = &cobra.Command{
|
||||
Use: "load",
|
||||
Short: "Loads and validates a FLE type logfile",
|
||||
// Long: `A longer description that spans multiple lines and likely contains examples
|
||||
// and usage of using your command. For example:
|
||||
// Long: `A longer description that spans multiple lines and likely contains examples
|
||||
// and usage of using your command. For example:
|
||||
|
||||
// Cobra is a CLI library for Go that empowers applications.
|
||||
// This application is a tool to generate the needed files
|
||||
// to quickly create a Cobra application.`,
|
||||
// Cobra is a CLI library for Go that empowers applications.
|
||||
// This application is a tool to generate the needed files
|
||||
// to quickly create a Cobra application.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
//fmt.Println("load called")
|
||||
//fmt.Println("Inputfile: ",inputFilename)
|
||||
|
@ -58,19 +59,19 @@ func init() {
|
|||
|
||||
func loadFile() {
|
||||
file, err := os.Open(inputFilename)
|
||||
|
||||
|
||||
if err != nil {
|
||||
log.Fatalf("failed opening file: %s", err)
|
||||
}
|
||||
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
scanner.Split(bufio.ScanLines)
|
||||
var txtlines []string
|
||||
|
||||
|
||||
for scanner.Scan() {
|
||||
txtlines = append(txtlines, scanner.Text())
|
||||
}
|
||||
|
||||
|
||||
file.Close()
|
||||
|
||||
regexpLineComment, _ := regexp.Compile("^#")
|
||||
|
@ -79,14 +80,13 @@ func loadFile() {
|
|||
regexpStartMultiLineComment, _ := regexp.Compile("^{")
|
||||
regexpEndMultiLineComment, _ := regexp.Compile("}$")
|
||||
regexpHeaderMyCall, _ := regexp.Compile("(?i)^mycall ")
|
||||
regexpHeaderOperator, _ := regexp.Compile("(?i)^operator ")
|
||||
regexpHeaderOperator, _ := regexp.Compile("(?i)^operator ")
|
||||
regexpHeaderMyWwff, _ := regexp.Compile("(?i)^mywwff ")
|
||||
regexpHeaderMySota, _ := regexp.Compile("(?i)^mysota ")
|
||||
regexpHeaderQslMsg, _ := regexp.Compile("(?i)^qslmsg ")
|
||||
regexpHeaderNickname, _ := regexp.Compile("(?i)^nickname ")
|
||||
regexpHeaderDate, _ := regexp.Compile("(?i)^date ")
|
||||
|
||||
|
||||
headerMyCall := ""
|
||||
headerOperator := ""
|
||||
headerMyWWFF := ""
|
||||
|
@ -96,14 +96,13 @@ func loadFile() {
|
|||
headerDate := ""
|
||||
lineCount := 0
|
||||
|
||||
var isInMultiLine = false
|
||||
var isInMultiLine = false
|
||||
var cleanedInput []string
|
||||
var errorLog []string
|
||||
|
||||
var previousLogLine LogLine
|
||||
var fullLog []LogLine
|
||||
|
||||
|
||||
|
||||
//Loop through all the stored lined
|
||||
for _, eachline := range txtlines {
|
||||
lineCount++
|
||||
|
@ -113,25 +112,25 @@ func loadFile() {
|
|||
// ****
|
||||
|
||||
//Skip the line if it starts with "#"
|
||||
if(regexpLineComment.MatchString(eachline)) {
|
||||
if regexpLineComment.MatchString(eachline) {
|
||||
continue
|
||||
}
|
||||
//Skip if line is empty or blank
|
||||
if((len(eachline) == 0) || (regexpOnlySpaces.MatchString(eachline))) {
|
||||
if (len(eachline) == 0) || (regexpOnlySpaces.MatchString(eachline)) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Process multi-line comments
|
||||
if(regexpStartMultiLineComment.MatchString(eachline)) {
|
||||
if regexpStartMultiLineComment.MatchString(eachline) {
|
||||
//Single-line "multi-line" coment
|
||||
if(regexpSingleMultiLineComment.MatchString(eachline)) {
|
||||
continue
|
||||
if regexpSingleMultiLineComment.MatchString(eachline) {
|
||||
continue
|
||||
}
|
||||
isInMultiLine = true
|
||||
continue
|
||||
}
|
||||
if(isInMultiLine) {
|
||||
if(regexpEndMultiLineComment.MatchString(eachline)) {
|
||||
if isInMultiLine {
|
||||
if regexpEndMultiLineComment.MatchString(eachline) {
|
||||
isInMultiLine = false
|
||||
}
|
||||
continue
|
||||
|
@ -142,29 +141,29 @@ func loadFile() {
|
|||
// ****
|
||||
|
||||
//My Call
|
||||
if(regexpHeaderMyCall.MatchString(eachline)) {
|
||||
if regexpHeaderMyCall.MatchString(eachline) {
|
||||
errorMsg := ""
|
||||
myCallList := regexpHeaderMyCall.Split(eachline,-1)
|
||||
if(len(myCallList[1]) > 0) {
|
||||
myCallList := regexpHeaderMyCall.Split(eachline, -1)
|
||||
if len(myCallList[1]) > 0 {
|
||||
headerMyCall, errorMsg = ValidateCall(myCallList[1])
|
||||
cleanedInput = append(cleanedInput, fmt.Sprintf("My call: %s", headerMyCall))
|
||||
if(len(errorMsg) != 0) {
|
||||
errorLog = append(errorLog, fmt.Sprintf("Invalid myCall at line %d: %s (%s)",lineCount, myCallList[1], errorMsg))
|
||||
if len(errorMsg) != 0 {
|
||||
errorLog = append(errorLog, fmt.Sprintf("Invalid myCall at line %d: %s (%s)", lineCount, myCallList[1], errorMsg))
|
||||
}
|
||||
}
|
||||
//If there is no data after the marker, we just skip the data.
|
||||
//If there is no data after the marker, we just skip the data.
|
||||
continue
|
||||
}
|
||||
|
||||
//Operator
|
||||
if(regexpHeaderOperator.MatchString(eachline)) {
|
||||
if regexpHeaderOperator.MatchString(eachline) {
|
||||
errorMsg := ""
|
||||
myOperatorList := regexpHeaderOperator.Split(eachline,-1)
|
||||
if(len(myOperatorList[1]) > 0) {
|
||||
myOperatorList := regexpHeaderOperator.Split(eachline, -1)
|
||||
if len(myOperatorList[1]) > 0 {
|
||||
headerOperator, errorMsg = ValidateCall(myOperatorList[1])
|
||||
cleanedInput = append(cleanedInput, fmt.Sprintf("Operator: %s", headerOperator))
|
||||
if(len(errorMsg) != 0) {
|
||||
errorLog = append(errorLog, fmt.Sprintf("Invalid Operator at line %d: %s (%s)",lineCount, myOperatorList[1], errorMsg))
|
||||
if len(errorMsg) != 0 {
|
||||
errorLog = append(errorLog, fmt.Sprintf("Invalid Operator at line %d: %s (%s)", lineCount, myOperatorList[1], errorMsg))
|
||||
}
|
||||
}
|
||||
//If there is no data after the marker, we just skip the data.
|
||||
|
@ -172,29 +171,29 @@ func loadFile() {
|
|||
}
|
||||
|
||||
// My WWFF
|
||||
if(regexpHeaderMyWwff.MatchString(eachline)) {
|
||||
if regexpHeaderMyWwff.MatchString(eachline) {
|
||||
errorMsg := ""
|
||||
myWwffList := regexpHeaderMyWwff.Split(eachline,-1)
|
||||
if(len(myWwffList[1]) > 0) {
|
||||
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 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)) {
|
||||
if regexpHeaderMySota.MatchString(eachline) {
|
||||
errorMsg := ""
|
||||
mySotaList := regexpHeaderMySota.Split(eachline,-1)
|
||||
if(len(mySotaList[1]) > 0) {
|
||||
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 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.
|
||||
|
@ -202,9 +201,9 @@ func loadFile() {
|
|||
}
|
||||
|
||||
//QSL Message
|
||||
if(regexpHeaderQslMsg.MatchString(eachline)) {
|
||||
myQslMsgList := regexpHeaderQslMsg.Split(eachline,-1)
|
||||
if(len(myQslMsgList[1]) > 0) {
|
||||
if regexpHeaderQslMsg.MatchString(eachline) {
|
||||
myQslMsgList := regexpHeaderQslMsg.Split(eachline, -1)
|
||||
if len(myQslMsgList[1]) > 0 {
|
||||
headerQslMsg = myQslMsgList[1]
|
||||
cleanedInput = append(cleanedInput, fmt.Sprintf("QSL Message: %s", headerQslMsg))
|
||||
}
|
||||
|
@ -213,9 +212,9 @@ func loadFile() {
|
|||
}
|
||||
|
||||
//Nickname
|
||||
if(regexpHeaderNickname.MatchString(eachline)) {
|
||||
myNicknameList := regexpHeaderNickname.Split(eachline,-1)
|
||||
if(len(myNicknameList[1]) > 0) {
|
||||
if regexpHeaderNickname.MatchString(eachline) {
|
||||
myNicknameList := regexpHeaderNickname.Split(eachline, -1)
|
||||
if len(myNicknameList[1]) > 0 {
|
||||
headerNickname = myNicknameList[1]
|
||||
cleanedInput = append(cleanedInput, fmt.Sprintf("eQSL Nickmane: %s", headerNickname))
|
||||
}
|
||||
|
@ -224,23 +223,23 @@ func loadFile() {
|
|||
}
|
||||
|
||||
// Date
|
||||
if(regexpHeaderDate.MatchString(eachline)) {
|
||||
if regexpHeaderDate.MatchString(eachline) {
|
||||
errorMsg := ""
|
||||
myDateList := regexpHeaderDate.Split(eachline,-1)
|
||||
if(len(myDateList[1]) > 0) {
|
||||
myDateList := regexpHeaderDate.Split(eachline, -1)
|
||||
if len(myDateList[1]) > 0 {
|
||||
headerDate, errorMsg = ValidateDate(myDateList[1])
|
||||
if(len(errorMsg) != 0) {
|
||||
errorLog = append(errorLog, fmt.Sprintf("Invalid Date at line %d: %s (%s)",lineCount, myDateList[1], errorMsg))
|
||||
if len(errorMsg) != 0 {
|
||||
errorLog = append(errorLog, fmt.Sprintf("Invalid Date at line %d: %s (%s)", lineCount, myDateList[1], errorMsg))
|
||||
}
|
||||
}
|
||||
}
|
||||
//If there is no data after the marker, we just skip the data.
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// ****
|
||||
// ** Process the data block
|
||||
// ****
|
||||
|
||||
|
||||
// Load the header values in the previousLogLine
|
||||
previousLogLine.MyCall = headerMyCall
|
||||
previousLogLine.Operator = headerOperator
|
||||
|
@ -256,7 +255,7 @@ func loadFile() {
|
|||
fullLog = append(fullLog, logline)
|
||||
}
|
||||
if errorLine != "" {
|
||||
errorLog = append(errorLog, fmt.Sprintf("Parsing error at line %d: %s ",lineCount,errorLine))
|
||||
errorLog = append(errorLog, fmt.Sprintf("Parsing error at line %d: %s ", lineCount, errorLine))
|
||||
}
|
||||
previousLogLine = logline
|
||||
//Go back to the top (Continue not necessary)
|
||||
|
@ -279,14 +278,13 @@ func loadFile() {
|
|||
fmt.Print(SprintLogInColumn(filledLogLine))
|
||||
}
|
||||
|
||||
if(len(errorLog) != 0){
|
||||
if len(errorLog) != 0 {
|
||||
fmt.Println("\nProcessing errors:")
|
||||
for _, errorLogLine := range errorLog {
|
||||
fmt.Println(errorLogLine)
|
||||
}
|
||||
} else {
|
||||
fmt.Println("\nSuccesfuly parsed ",lineCount, " lines.")
|
||||
fmt.Println("\nSuccesfuly parsed ", lineCount, " lines.")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
package cmd
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
|
@ -15,7 +16,6 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
@ -26,32 +26,31 @@ import (
|
|||
|
||||
//TODO: validate a record for minimal values
|
||||
|
||||
|
||||
// LogLine is used to store all the data of a single log line
|
||||
type LogLine struct {
|
||||
Date string
|
||||
MyCall string
|
||||
Operator string
|
||||
MyWWFF string
|
||||
MySOTA string
|
||||
QslMsg string
|
||||
Nickname string
|
||||
Mode string
|
||||
ModeType string
|
||||
Band string
|
||||
Date string
|
||||
MyCall string
|
||||
Operator string
|
||||
MyWWFF string
|
||||
MySOTA string
|
||||
QslMsg string
|
||||
Nickname string
|
||||
Mode string
|
||||
ModeType string
|
||||
Band string
|
||||
BandLowerLimit float64
|
||||
BandUpperLimit float64
|
||||
Frequency string
|
||||
Time string
|
||||
Call string
|
||||
Comment string
|
||||
QSLmsg string
|
||||
OMname string
|
||||
GridLoc string
|
||||
RSTsent string
|
||||
RSTrcvd string
|
||||
WWFF string
|
||||
SOTA string
|
||||
Frequency string
|
||||
Time string
|
||||
Call string
|
||||
Comment string
|
||||
QSLmsg string
|
||||
OMname string
|
||||
GridLoc string
|
||||
RSTsent string
|
||||
RSTrcvd string
|
||||
WWFF string
|
||||
SOTA string
|
||||
}
|
||||
|
||||
var regexpIsFullTime = regexp.MustCompile("^[0-2]{1}[0-9]{3}$")
|
||||
|
@ -62,7 +61,7 @@ var regexpIsRst = regexp.MustCompile("^[\\d]{1,3}$")
|
|||
var regexpIsFreq = regexp.MustCompile("^[\\d]+\\.[\\d]+$")
|
||||
|
||||
// ParseLine cuts a FLE line into useful bits
|
||||
func ParseLine(inputStr string, previousLine LogLine) (logLine LogLine, errorMsg string){
|
||||
func ParseLine(inputStr string, previousLine LogLine) (logLine LogLine, errorMsg string) {
|
||||
//TODO: input null protection?
|
||||
|
||||
//Flag telling that we are processing data to the right of the callsign
|
||||
|
@ -85,23 +84,22 @@ func ParseLine(inputStr string, previousLine LogLine) (logLine LogLine, errorMsg
|
|||
|
||||
//TODO: what happens when we have <> or when there are multiple comments
|
||||
//TODO: Refactor this! it is ugly
|
||||
comment,inputStr := getBraketedData(inputStr, COMMENT)
|
||||
comment, inputStr := getBraketedData(inputStr, COMMENT)
|
||||
if comment != "" {
|
||||
logLine.Comment = comment
|
||||
}
|
||||
|
||||
QSLmsg,inputStr := getBraketedData(inputStr, QSL)
|
||||
QSLmsg, inputStr := getBraketedData(inputStr, QSL)
|
||||
if QSLmsg != "" {
|
||||
logLine.QSLmsg = QSLmsg
|
||||
}
|
||||
|
||||
|
||||
elements := strings.Fields(inputStr)
|
||||
|
||||
for _, element := range elements {
|
||||
|
||||
// Is it a mode?
|
||||
if lookupMode( strings.ToUpper(element)) {
|
||||
if lookupMode(strings.ToUpper(element)) {
|
||||
logLine.Mode = strings.ToUpper(element)
|
||||
//TODO: improve this: what if the band is at the end of the line
|
||||
// Set the default RST depending of the mode
|
||||
|
@ -119,7 +117,7 @@ func ParseLine(inputStr string, previousLine LogLine) (logLine LogLine, errorMsg
|
|||
}
|
||||
|
||||
// Is it a band?
|
||||
isBandElement, bandLowerLimit, bandUpperLimit := IsBand(element)
|
||||
isBandElement, bandLowerLimit, bandUpperLimit := IsBand(element)
|
||||
if isBandElement {
|
||||
logLine.Band = strings.ToLower(element)
|
||||
logLine.BandLowerLimit = bandLowerLimit
|
||||
|
@ -130,10 +128,10 @@ func ParseLine(inputStr string, previousLine LogLine) (logLine LogLine, errorMsg
|
|||
// Is it a Frequency?
|
||||
if regexpIsFreq.MatchString(element) {
|
||||
var qrg float64
|
||||
qrg,_ = strconv.ParseFloat(element, 32)
|
||||
if (logLine.BandLowerLimit != 0.0) && (logLine.BandUpperLimit != 0.0){
|
||||
qrg, _ = strconv.ParseFloat(element, 32)
|
||||
if (logLine.BandLowerLimit != 0.0) && (logLine.BandUpperLimit != 0.0) {
|
||||
if (qrg >= logLine.BandLowerLimit) && (qrg <= logLine.BandUpperLimit) {
|
||||
logLine.Frequency = fmt.Sprintf("%.3f",qrg)
|
||||
logLine.Frequency = fmt.Sprintf("%.3f", qrg)
|
||||
} else {
|
||||
logLine.Frequency = ""
|
||||
errorMsg = errorMsg + " Frequency " + element + " is invalid for " + logLine.Band + " band"
|
||||
|
@ -171,18 +169,16 @@ func ParseLine(inputStr string, previousLine LogLine) (logLine LogLine, errorMsg
|
|||
continue
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Is it the OM's name (starting with "@")
|
||||
if regexpIsOMname.MatchString(element) {
|
||||
logLine.OMname = strings.TrimLeft(element, "@")
|
||||
logLine.OMname = strings.TrimLeft(element, "@")
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
// Is it the Grid Locator (starting with "#")
|
||||
if regexpIsGridLoc.MatchString(element) {
|
||||
logLine.GridLoc = strings.TrimLeft(element, "#")
|
||||
logLine.GridLoc = strings.TrimLeft(element, "#")
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -194,18 +190,18 @@ func ParseLine(inputStr string, previousLine LogLine) (logLine LogLine, errorMsg
|
|||
case 1:
|
||||
if logLine.ModeType == "CW" {
|
||||
workRST = "5" + element + "9"
|
||||
} else {
|
||||
} else {
|
||||
if logLine.ModeType == "PHONE" {
|
||||
workRST = "5" + element
|
||||
}
|
||||
}
|
||||
}
|
||||
case 2:
|
||||
if logLine.ModeType == "CW" {
|
||||
workRST = element + "9"
|
||||
} else {
|
||||
} else {
|
||||
if logLine.ModeType == "PHONE" {
|
||||
workRST = element
|
||||
}
|
||||
}
|
||||
}
|
||||
case 3:
|
||||
if logLine.ModeType == "CW" {
|
||||
|
@ -225,14 +221,14 @@ func ParseLine(inputStr string, previousLine LogLine) (logLine LogLine, errorMsg
|
|||
}
|
||||
|
||||
// Is it a WWFF to WWFF reference?
|
||||
workRef, wwffErr := ValidateWwff(element)
|
||||
workRef, wwffErr := ValidateWwff(element)
|
||||
if wwffErr == "" {
|
||||
logLine.WWFF = workRef
|
||||
continue
|
||||
}
|
||||
|
||||
// Is it a WWFF to WWFF reference?
|
||||
workRef, sotaErr := ValidateSota(element)
|
||||
workRef, sotaErr := ValidateSota(element)
|
||||
if sotaErr == "" {
|
||||
logLine.SOTA = workRef
|
||||
continue
|
||||
|
@ -258,15 +254,14 @@ func ParseLine(inputStr string, previousLine LogLine) (logLine LogLine, errorMsg
|
|||
return logLine, errorMsg
|
||||
}
|
||||
|
||||
|
||||
func lookupMode(lookup string) bool {
|
||||
switch lookup {
|
||||
case
|
||||
"CW",
|
||||
"SSB",
|
||||
"CW",
|
||||
"SSB",
|
||||
"AM",
|
||||
"FM",
|
||||
"RTTY",
|
||||
"RTTY",
|
||||
"FT8",
|
||||
"PSK",
|
||||
"JT65",
|
||||
|
@ -310,11 +305,8 @@ func lookupMode(lookup string) bool {
|
|||
"V4",
|
||||
"VOI",
|
||||
"WINMOR",
|
||||
"WSPR":
|
||||
"WSPR":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
|
||||
func TestParseLine(t *testing.T) {
|
||||
type args struct {
|
||||
inputStr string
|
||||
|
@ -18,94 +17,94 @@ func TestParseLine(t *testing.T) {
|
|||
wantErrorMsg string
|
||||
}{
|
||||
{
|
||||
"Parse band and mode only",
|
||||
args{ inputStr: "40M cw", previousLine: LogLine{ Mode: "SSB", }},
|
||||
LogLine{ Band: "40m", BandLowerLimit: 7, BandUpperLimit: 7.3, Mode: "CW", ModeType: "CW", RSTsent: "599", RSTrcvd: "599"}, "",
|
||||
"Parse band and mode only",
|
||||
args{inputStr: "40M cw", previousLine: LogLine{Mode: "SSB"}},
|
||||
LogLine{Band: "40m", BandLowerLimit: 7, BandUpperLimit: 7.3, Mode: "CW", ModeType: "CW", RSTsent: "599", RSTrcvd: "599"}, "",
|
||||
},
|
||||
{
|
||||
"Parse for time",
|
||||
args{ inputStr: "1314 g3noh", previousLine: LogLine{ Mode: "SSB", }},
|
||||
LogLine{ Time: "1314", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
"Parse for time",
|
||||
args{inputStr: "1314 g3noh", previousLine: LogLine{Mode: "SSB"}},
|
||||
LogLine{Time: "1314", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
},
|
||||
{
|
||||
"Parse partial time - 1",
|
||||
args{ inputStr: "4 g3noh", previousLine: LogLine{ Time: "", Mode: "SSB", }},
|
||||
LogLine{ Time: "4", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "", //TODO: should fail
|
||||
"Parse partial time - 1",
|
||||
args{inputStr: "4 g3noh", previousLine: LogLine{Time: "", Mode: "SSB"}},
|
||||
LogLine{Time: "4", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "", //TODO: should fail
|
||||
},
|
||||
{
|
||||
"Parse partial time - 2",
|
||||
args{ inputStr: "15 g3noh", previousLine: LogLine{ Time: "1200", Mode: "SSB", }},
|
||||
LogLine{ Time: "1215", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
"Parse partial time - 2",
|
||||
args{inputStr: "15 g3noh", previousLine: LogLine{Time: "1200", Mode: "SSB"}},
|
||||
LogLine{Time: "1215", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
},
|
||||
{
|
||||
"Parse partial time - 3",
|
||||
args{ inputStr: "4 g3noh", previousLine: LogLine{ Time: "1200", Mode: "SSB", }},
|
||||
LogLine{ Time: "1204", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
"Parse partial time - 3",
|
||||
args{inputStr: "4 g3noh", previousLine: LogLine{Time: "1200", Mode: "SSB"}},
|
||||
LogLine{Time: "1204", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
},
|
||||
{
|
||||
"Parse for comment",
|
||||
args{ inputStr: "4 g3noh <PSE QSL Direct>", previousLine: LogLine{ Mode: "SSB", }},
|
||||
LogLine{ Time: "4", Comment: "PSE QSL Direct", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
"Parse for comment",
|
||||
args{inputStr: "4 g3noh <PSE QSL Direct>", previousLine: LogLine{Mode: "SSB"}},
|
||||
LogLine{Time: "4", Comment: "PSE QSL Direct", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
},
|
||||
{
|
||||
"Parse for QSL",
|
||||
args{ inputStr: "g3noh [Custom QSL message]", previousLine: LogLine{ Mode: "SSB", }},
|
||||
LogLine{ QSLmsg: "Custom QSL message", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
"Parse for QSL",
|
||||
args{inputStr: "g3noh [Custom QSL message]", previousLine: LogLine{Mode: "SSB"}},
|
||||
LogLine{QSLmsg: "Custom QSL message", Call: "G3NOH", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
},
|
||||
{
|
||||
"Wrong mode",
|
||||
args{ inputStr: "cww", previousLine: LogLine{ Mode: "SSB", }},
|
||||
LogLine{ Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "Unable to parse cww ",
|
||||
"Wrong mode",
|
||||
args{inputStr: "cww", previousLine: LogLine{Mode: "SSB"}},
|
||||
LogLine{Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "Unable to parse cww ",
|
||||
},
|
||||
{
|
||||
"Parse OM name",
|
||||
args{ inputStr: "@Jean", previousLine: LogLine{ Mode: "SSB", }},
|
||||
LogLine{ OMname: "Jean", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
"Parse OM name",
|
||||
args{inputStr: "@Jean", previousLine: LogLine{Mode: "SSB"}},
|
||||
LogLine{OMname: "Jean", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
},
|
||||
{
|
||||
"Parse Grid locator",
|
||||
args{ inputStr: "#grid", previousLine: LogLine{ Mode: "SSB", }},
|
||||
LogLine{ GridLoc: "grid", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
"Parse Grid locator",
|
||||
args{inputStr: "#grid", previousLine: LogLine{Mode: "SSB"}},
|
||||
LogLine{GridLoc: "grid", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
},
|
||||
{
|
||||
"Parse frequency",
|
||||
args{ inputStr: "14.153 on4kjm", previousLine: LogLine{ Mode: "SSB", Band: "20m", BandLowerLimit: 14.0, BandUpperLimit: 14.35}},
|
||||
LogLine{ Band: "20m", BandLowerLimit: 14.0, BandUpperLimit: 14.35, Frequency: "14.153", Call: "ON4KJM" ,Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
"Parse frequency",
|
||||
args{inputStr: "14.153 on4kjm", previousLine: LogLine{Mode: "SSB", Band: "20m", BandLowerLimit: 14.0, BandUpperLimit: 14.35}},
|
||||
LogLine{Band: "20m", BandLowerLimit: 14.0, BandUpperLimit: 14.35, Frequency: "14.153", Call: "ON4KJM", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
},
|
||||
{
|
||||
"Parse frequency out of limit",
|
||||
args{ inputStr: "14.453 on4kjm", previousLine: LogLine{ Mode: "SSB", Band: "20m", BandLowerLimit: 14.0, BandUpperLimit: 14.35}},
|
||||
LogLine{ Band: "20m", BandLowerLimit: 14.0, BandUpperLimit: 14.35, Call: "ON4KJM" ,Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, " Frequency 14.453 is invalid for 20m band",
|
||||
"Parse frequency out of limit",
|
||||
args{inputStr: "14.453 on4kjm", previousLine: LogLine{Mode: "SSB", Band: "20m", BandLowerLimit: 14.0, BandUpperLimit: 14.35}},
|
||||
LogLine{Band: "20m", BandLowerLimit: 14.0, BandUpperLimit: 14.35, Call: "ON4KJM", Mode: "SSB", RSTsent: "59", RSTrcvd: "59"}, " Frequency 14.453 is invalid for 20m band",
|
||||
},
|
||||
{
|
||||
"parse partial RST (sent) - CW",
|
||||
args{ inputStr: "1230 on4kjm 5", previousLine: LogLine{ Mode: "CW", ModeType: "CW"}},
|
||||
LogLine{ Call: "ON4KJM", Time: "1230", RSTsent: "559", RSTrcvd: "599", Mode: "CW", ModeType: "CW"}, "",
|
||||
"parse partial RST (sent) - CW",
|
||||
args{inputStr: "1230 on4kjm 5", previousLine: LogLine{Mode: "CW", ModeType: "CW"}},
|
||||
LogLine{Call: "ON4KJM", Time: "1230", RSTsent: "559", RSTrcvd: "599", Mode: "CW", ModeType: "CW"}, "",
|
||||
},
|
||||
{
|
||||
"parse partial RST (received) - CW",
|
||||
args{ inputStr: "1230 on4kjm 5 44", previousLine: LogLine{ Mode: "CW", ModeType: "CW"}},
|
||||
LogLine{ Call: "ON4KJM", Time: "1230", RSTsent: "559", RSTrcvd: "449", Mode: "CW", ModeType: "CW"}, "",
|
||||
"parse partial RST (received) - CW",
|
||||
args{inputStr: "1230 on4kjm 5 44", previousLine: LogLine{Mode: "CW", ModeType: "CW"}},
|
||||
LogLine{Call: "ON4KJM", Time: "1230", RSTsent: "559", RSTrcvd: "449", Mode: "CW", ModeType: "CW"}, "",
|
||||
},
|
||||
{
|
||||
"parse full RST (received) - CW",
|
||||
args{ inputStr: "1230 on4kjm 5 448", previousLine: LogLine{ Mode: "CW", ModeType: "CW"}},
|
||||
LogLine{ Call: "ON4KJM", Time: "1230", RSTsent: "559", RSTrcvd: "448", Mode: "CW", ModeType: "CW"}, "",
|
||||
"parse full RST (received) - CW",
|
||||
args{inputStr: "1230 on4kjm 5 448", previousLine: LogLine{Mode: "CW", ModeType: "CW"}},
|
||||
LogLine{Call: "ON4KJM", Time: "1230", RSTsent: "559", RSTrcvd: "448", Mode: "CW", ModeType: "CW"}, "",
|
||||
},
|
||||
{
|
||||
"parse partial report (sent) - FM",
|
||||
args{ inputStr: "1230 on4kjm 5", previousLine: LogLine{ Mode: "FM", ModeType: "PHONE"}},
|
||||
LogLine{ Call: "ON4KJM", Time: "1230", RSTsent: "55", RSTrcvd: "59", Mode: "FM", ModeType: "PHONE"}, "",
|
||||
"parse partial report (sent) - FM",
|
||||
args{inputStr: "1230 on4kjm 5", previousLine: LogLine{Mode: "FM", ModeType: "PHONE"}},
|
||||
LogLine{Call: "ON4KJM", Time: "1230", RSTsent: "55", RSTrcvd: "59", Mode: "FM", ModeType: "PHONE"}, "",
|
||||
},
|
||||
{
|
||||
"parse partial report (received) - FM",
|
||||
args{ inputStr: "1230 on4kjm 5 44", previousLine: LogLine{ Mode: "FM", ModeType: "PHONE"}},
|
||||
LogLine{ Call: "ON4KJM", Time: "1230", RSTsent: "55", RSTrcvd: "44", Mode: "FM", ModeType: "PHONE"}, "",
|
||||
"parse partial report (received) - FM",
|
||||
args{inputStr: "1230 on4kjm 5 44", previousLine: LogLine{Mode: "FM", ModeType: "PHONE"}},
|
||||
LogLine{Call: "ON4KJM", Time: "1230", RSTsent: "55", RSTrcvd: "44", Mode: "FM", ModeType: "PHONE"}, "",
|
||||
},
|
||||
{
|
||||
"Incompatible report",
|
||||
args{ inputStr: "1230 on4kjm 5 599", previousLine: LogLine{ Mode: "FM", ModeType: "PHONE"}},
|
||||
LogLine{ Call: "ON4KJM", Time: "1230", RSTsent: "55", RSTrcvd: "*599", Mode: "FM", ModeType: "PHONE"}, "Invalid report (599) for PHONE mode ",
|
||||
"Incompatible report",
|
||||
args{inputStr: "1230 on4kjm 5 599", previousLine: LogLine{Mode: "FM", ModeType: "PHONE"}},
|
||||
LogLine{Call: "ON4KJM", Time: "1230", RSTsent: "55", RSTrcvd: "*599", Mode: "FM", ModeType: "PHONE"}, "Invalid report (599) for PHONE mode ",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
@ -133,34 +132,34 @@ func TestHappyParseLine(t *testing.T) {
|
|||
wantErrorMsg string
|
||||
}{
|
||||
{
|
||||
"test1",
|
||||
args{ inputStr: "1202 g4elz",
|
||||
previousLine: LogLine{ Mode: "CW", ModeType: "CW", Band: "40m", BandLowerLimit: 7, BandUpperLimit: 7.3}},
|
||||
LogLine{ Time: "1202", Call: "G4ELZ", Band: "40m", BandLowerLimit: 7, BandUpperLimit: 7.3, Mode: "CW", ModeType: "CW", RSTsent: "599", RSTrcvd: "599"}, "",
|
||||
"test1",
|
||||
args{inputStr: "1202 g4elz",
|
||||
previousLine: LogLine{Mode: "CW", ModeType: "CW", Band: "40m", BandLowerLimit: 7, BandUpperLimit: 7.3}},
|
||||
LogLine{Time: "1202", Call: "G4ELZ", Band: "40m", BandLowerLimit: 7, BandUpperLimit: 7.3, Mode: "CW", ModeType: "CW", RSTsent: "599", RSTrcvd: "599"}, "",
|
||||
},
|
||||
{
|
||||
"test2",
|
||||
args{ inputStr: "4 g3noh <PSE QSL Direct>",
|
||||
previousLine: LogLine{ Time: "1202", Mode: "CW", ModeType: "CW", Band: "40m", BandLowerLimit: 7, BandUpperLimit: 7.3}},
|
||||
LogLine{ Time: "1204", Call: "G3NOH", Band: "40m", BandLowerLimit: 7, BandUpperLimit: 7.3, Mode: "CW", ModeType: "CW", Comment: "PSE QSL Direct", RSTsent: "599", RSTrcvd: "599"}, "",
|
||||
"test2",
|
||||
args{inputStr: "4 g3noh <PSE QSL Direct>",
|
||||
previousLine: LogLine{Time: "1202", Mode: "CW", ModeType: "CW", Band: "40m", BandLowerLimit: 7, BandUpperLimit: 7.3}},
|
||||
LogLine{Time: "1204", Call: "G3NOH", Band: "40m", BandLowerLimit: 7, BandUpperLimit: 7.3, Mode: "CW", ModeType: "CW", Comment: "PSE QSL Direct", RSTsent: "599", RSTrcvd: "599"}, "",
|
||||
},
|
||||
{
|
||||
"test3",
|
||||
args{ inputStr: "1227 gw4gte <Dave>",
|
||||
previousLine: LogLine{ Time: "1202", Mode: "FM", ModeType: "PHONE", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148}},
|
||||
LogLine{ Time: "1227", Call: "GW4GTE", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148, Mode: "FM", ModeType: "PHONE", Comment: "Dave", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
"test3",
|
||||
args{inputStr: "1227 gw4gte <Dave>",
|
||||
previousLine: LogLine{Time: "1202", Mode: "FM", ModeType: "PHONE", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148}},
|
||||
LogLine{Time: "1227", Call: "GW4GTE", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148, Mode: "FM", ModeType: "PHONE", Comment: "Dave", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
},
|
||||
{
|
||||
"test4",
|
||||
args{ inputStr: "8 gw0tlk/m gwff-0021",
|
||||
previousLine: LogLine{ Time: "1227", Mode: "FM", ModeType: "PHONE", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148}},
|
||||
LogLine{ Time: "1228", Call: "GW0TLK/M", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148, Mode: "FM", ModeType: "PHONE", WWFF: "GWFF-0021", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
"test4",
|
||||
args{inputStr: "8 gw0tlk/m gwff-0021",
|
||||
previousLine: LogLine{Time: "1227", Mode: "FM", ModeType: "PHONE", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148}},
|
||||
LogLine{Time: "1228", Call: "GW0TLK/M", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148, Mode: "FM", ModeType: "PHONE", WWFF: "GWFF-0021", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
},
|
||||
{
|
||||
"test5",
|
||||
args{ inputStr: "7 dl0dan/p dlff-0002 dl/al-044",
|
||||
previousLine: LogLine{ Time: "1220", Mode: "FM", ModeType: "PHONE", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148}},
|
||||
LogLine{ Time: "1227", Call: "DL0DAN/P", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148, Mode: "FM", ModeType: "PHONE", WWFF: "DLFF-0002", SOTA: "DL/AL-044", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
"test5",
|
||||
args{inputStr: "7 dl0dan/p dlff-0002 dl/al-044",
|
||||
previousLine: LogLine{Time: "1220", Mode: "FM", ModeType: "PHONE", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148}},
|
||||
LogLine{Time: "1227", Call: "DL0DAN/P", Band: "2m", BandLowerLimit: 144, BandUpperLimit: 148, Mode: "FM", ModeType: "PHONE", WWFF: "DLFF-0002", SOTA: "DL/AL-044", RSTsent: "59", RSTrcvd: "59"}, "",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
|
@ -174,4 +173,4 @@ func TestHappyParseLine(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
15
cmd/root.go
15
cmd/root.go
|
@ -1,4 +1,5 @@
|
|||
package cmd
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
|
@ -36,15 +37,15 @@ var inputFilename string
|
|||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "FLEcli",
|
||||
Short: "A Command Line \"Fast Log Entry\" (FLE) processor",
|
||||
Use: "FLEcli",
|
||||
Short: "A Command Line \"Fast Log Entry\" (FLE) processor",
|
||||
TraverseChildren: true,
|
||||
// Long: `A longer description that spans multiple lines and likely contains
|
||||
// examples and usage of using your application. For example:
|
||||
// Long: `A longer description that spans multiple lines and likely contains
|
||||
// examples and usage of using your application. For example:
|
||||
|
||||
// Cobra is a CLI library for Go that empowers applications.
|
||||
// This application is a tool to generate the needed files
|
||||
// to quickly create a Cobra application.`,
|
||||
// Cobra is a CLI library for Go that empowers applications.
|
||||
// This application is a tool to generate the needed files
|
||||
// to quickly create a Cobra application.`,
|
||||
// Uncomment the following line if your bare application
|
||||
// has an action associated with it:
|
||||
// Run: func(cmd *cobra.Command, args []string) { },
|
||||
|
|
157
cmd/validate.go
157
cmd/validate.go
|
@ -1,4 +1,5 @@
|
|||
package cmd
|
||||
|
||||
/*
|
||||
Copyright © 2020 Jean-Marc Meessen, ON4KJM <on4kjm@gmail.com>
|
||||
|
||||
|
@ -16,24 +17,23 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
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).
|
||||
// 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"
|
||||
if validSotaRegexp.MatchString(inputStr) {
|
||||
return inputStr, ""
|
||||
}
|
||||
return wrongInputStr, "Invalid SOTA reference"
|
||||
}
|
||||
|
||||
var validWwffRegexp = regexp.MustCompile(`^[\d]{0,1}[A-Z]{1,2}FF-[\d]{4}$`)
|
||||
|
@ -43,14 +43,12 @@ var validWwffRegexp = regexp.MustCompile(`^[\d]{0,1}[A-Z]{1,2}FF-[\d]{4}$`)
|
|||
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"
|
||||
if validWwffRegexp.MatchString(inputStr) {
|
||||
return inputStr, ""
|
||||
}
|
||||
return wrongInputStr, "Invalid WWFF reference"
|
||||
}
|
||||
|
||||
|
||||
|
||||
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}$`)
|
||||
|
||||
|
@ -72,9 +70,9 @@ func ValidateCall(sign string) (call, errorMsg string) {
|
|||
if validCallRegexp.MatchString(sp[0]) {
|
||||
//Callisign with suffix (unchecked)
|
||||
return sign, ""
|
||||
}
|
||||
}
|
||||
//else we are dealing with a prefixed Callsign
|
||||
//validate the part that should contain the call (sp[1])
|
||||
//validate the part that should contain the call (sp[1])
|
||||
if !validCallRegexp.MatchString(sp[1]) {
|
||||
return wrongSign, "Invalid call"
|
||||
}
|
||||
|
@ -84,7 +82,7 @@ func ValidateCall(sign string) (call, errorMsg string) {
|
|||
}
|
||||
return sign, ""
|
||||
case 3:
|
||||
//validate the part that should contain the call (sp[1])
|
||||
//validate the part that should contain the call (sp[1])
|
||||
if !validCallRegexp.MatchString(sp[1]) {
|
||||
return wrongSign, "Invalid call"
|
||||
}
|
||||
|
@ -117,85 +115,84 @@ func ValidateDate(inputStr string) (ref, errorMsg string) {
|
|||
//IsBand retuns true if the passed input string is a valid string
|
||||
func IsBand(inputStr string) (result bool, lowerLimit, upperLimit float64) {
|
||||
switch strings.ToLower(inputStr) {
|
||||
case "2190m":
|
||||
return true, 0.1357, 0.1378
|
||||
case "630m":
|
||||
return true, 0.472, 0.479
|
||||
case "560m":
|
||||
return true, 0.501, 0.504
|
||||
case "160m":
|
||||
return true, 1.8, 2.0
|
||||
case "80m":
|
||||
return true, 3.5, 4.0
|
||||
case "60m":
|
||||
return true, 5.06, 5.45
|
||||
case "40m":
|
||||
return true, 7.0, 7.3
|
||||
case "30m":
|
||||
return true, 10.1, 10.15
|
||||
case "20m":
|
||||
return true, 14.0, 14.35
|
||||
case "17m":
|
||||
return true, 18.068, 18.168
|
||||
case "15m":
|
||||
return true, 21.0, 21.45
|
||||
case "12m":
|
||||
return true, 24.890, 24.99
|
||||
case "10m":
|
||||
return true, 28.0, 29.7
|
||||
case "6m":
|
||||
return true, 50, 54
|
||||
case "4m":
|
||||
return true, 70, 71
|
||||
case "2m":
|
||||
return true, 144, 148
|
||||
case "1.25m":
|
||||
return true, 222, 225
|
||||
case "70cm":
|
||||
return true, 420, 450
|
||||
case "33cm":
|
||||
return true, 902, 928
|
||||
case "23cm":
|
||||
return true, 1240, 1300
|
||||
case "13cm":
|
||||
return true, 2300, 2450
|
||||
case "9cm":
|
||||
return true, 3300, 3500
|
||||
case "6cm":
|
||||
return true, 5650, 5925
|
||||
case "3cm":
|
||||
return true, 10000, 10500
|
||||
case "1.25cm":
|
||||
return true, 24000, 24250
|
||||
case "6mm":
|
||||
return true, 47000, 47200
|
||||
case "4mm":
|
||||
return true, 75500, 81000
|
||||
case "2.5mm":
|
||||
return true, 119980, 120020
|
||||
case "2mm":
|
||||
return true, 142000, 149000
|
||||
case "1mm":
|
||||
return true, 241000, 250000
|
||||
case "2190m":
|
||||
return true, 0.1357, 0.1378
|
||||
case "630m":
|
||||
return true, 0.472, 0.479
|
||||
case "560m":
|
||||
return true, 0.501, 0.504
|
||||
case "160m":
|
||||
return true, 1.8, 2.0
|
||||
case "80m":
|
||||
return true, 3.5, 4.0
|
||||
case "60m":
|
||||
return true, 5.06, 5.45
|
||||
case "40m":
|
||||
return true, 7.0, 7.3
|
||||
case "30m":
|
||||
return true, 10.1, 10.15
|
||||
case "20m":
|
||||
return true, 14.0, 14.35
|
||||
case "17m":
|
||||
return true, 18.068, 18.168
|
||||
case "15m":
|
||||
return true, 21.0, 21.45
|
||||
case "12m":
|
||||
return true, 24.890, 24.99
|
||||
case "10m":
|
||||
return true, 28.0, 29.7
|
||||
case "6m":
|
||||
return true, 50, 54
|
||||
case "4m":
|
||||
return true, 70, 71
|
||||
case "2m":
|
||||
return true, 144, 148
|
||||
case "1.25m":
|
||||
return true, 222, 225
|
||||
case "70cm":
|
||||
return true, 420, 450
|
||||
case "33cm":
|
||||
return true, 902, 928
|
||||
case "23cm":
|
||||
return true, 1240, 1300
|
||||
case "13cm":
|
||||
return true, 2300, 2450
|
||||
case "9cm":
|
||||
return true, 3300, 3500
|
||||
case "6cm":
|
||||
return true, 5650, 5925
|
||||
case "3cm":
|
||||
return true, 10000, 10500
|
||||
case "1.25cm":
|
||||
return true, 24000, 24250
|
||||
case "6mm":
|
||||
return true, 47000, 47200
|
||||
case "4mm":
|
||||
return true, 75500, 81000
|
||||
case "2.5mm":
|
||||
return true, 119980, 120020
|
||||
case "2mm":
|
||||
return true, 142000, 149000
|
||||
case "1mm":
|
||||
return true, 241000, 250000
|
||||
}
|
||||
return false, 0, 0
|
||||
}
|
||||
|
||||
|
||||
func getDefaultReport(mode string) (modeType, defaultReport string) {
|
||||
modeType = ""
|
||||
defaultReport = ""
|
||||
|
||||
switch mode {
|
||||
case "SSB", "AM", "FM" :
|
||||
case "SSB", "AM", "FM":
|
||||
modeType = "PHONE"
|
||||
defaultReport = "59"
|
||||
case "CW", "RTTY", "PSK":
|
||||
modeType = "CW"
|
||||
defaultReport = "599"
|
||||
case "JT65", "JT9", "JT6M", "JT4", "JT44", "FSK441", "FT8", "ISCAT", "MSK144", "QRA64", "T10", "WSPR" :
|
||||
case "JT65", "JT9", "JT6M", "JT4", "JT44", "FSK441", "FT8", "ISCAT", "MSK144", "QRA64", "T10", "WSPR":
|
||||
modeType = "DIGITAL"
|
||||
defaultReport = "-10"
|
||||
defaultReport = "-10"
|
||||
}
|
||||
return modeType, defaultReport
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue