From ab925ad2dd2d04a4f6e8fe0ce6bb61fa40dbc191 Mon Sep 17 00:00:00 2001 From: Jean-Marc MEESSEN Date: Thu, 25 Jun 2020 21:05:54 +0200 Subject: [PATCH] Reformat the sources with go fmt --- cmd/braketedData.go | 39 +++++----- cmd/braketedData_test.go | 42 +++++------ cmd/display.go | 15 ++-- cmd/load.go | 124 +++++++++++++++---------------- cmd/parse_line.go | 92 +++++++++++------------ cmd/parse_line_test.go | 151 +++++++++++++++++++------------------ cmd/root.go | 15 ++-- cmd/validate.go | 157 +++++++++++++++++++-------------------- 8 files changed, 312 insertions(+), 323 deletions(-) diff --git a/cmd/braketedData.go b/cmd/braketedData.go index 6f1236c..dd4eab7 100644 --- a/cmd/braketedData.go +++ b/cmd/braketedData.go @@ -1,4 +1,5 @@ package cmd + /* Copyright © 2020 Jean-Marc Meessen, ON4KJM @@ -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 -} \ No newline at end of file + cleanedLine = strings.Replace(inputLine, a+braketedData+b, "", 1) + return braketedData, cleanedLine +} diff --git a/cmd/braketedData_test.go b/cmd/braketedData_test.go index d79f81c..b63e711 100644 --- a/cmd/braketedData_test.go +++ b/cmd/braketedData_test.go @@ -14,45 +14,45 @@ func Test_getBraketedData(t *testing.T) { wantCleanedLine string }{ { - "Happy case: comment", - args{ inputLine: "aaaa bbbbb", braketType: COMMENT}, - "bracketed text", + "Happy case: comment", + args{inputLine: "aaaa 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 ", braketType: COMMENT}, - "bracketed text", + "Brackets at right", + args{inputLine: "aaaa bbbbb ", braketType: COMMENT}, + "bracketed text", "aaaa bbbbb ", }, { - "concatenated", - args{ inputLine: "aaaabbbbb", braketType: COMMENT}, - "bracketed text", + "concatenated", + args{inputLine: "aaaabbbbb", braketType: COMMENT}, + "bracketed text", "aaaabbbbb", }, { - "duplicated", - args{ inputLine: "aaaa bbbbb < double > cccc", braketType: COMMENT}, - "bracketed text", + "duplicated", + args{inputLine: "aaaa bbbbb < double > cccc", braketType: COMMENT}, + "bracketed text", "aaaa bbbbb < double > cccc", }, } diff --git a/cmd/display.go b/cmd/display.go index 623f1ce..307ff0c 100644 --- a/cmd/display.go +++ b/cmd/display.go @@ -1,4 +1,5 @@ package cmd + /* Copyright © 2020 Jean-Marc Meessen, ON4KJM @@ -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 -} \ No newline at end of file +} diff --git a/cmd/load.go b/cmd/load.go index dd30082..bc96e29 100644 --- a/cmd/load.go +++ b/cmd/load.go @@ -1,4 +1,5 @@ package cmd + /* Copyright © 2020 Jean-Marc Meessen, ON4KJM @@ -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.") } - } diff --git a/cmd/parse_line.go b/cmd/parse_line.go index 1e471d9..f109f6a 100644 --- a/cmd/parse_line.go +++ b/cmd/parse_line.go @@ -1,4 +1,5 @@ package cmd + /* Copyright © 2020 Jean-Marc Meessen, ON4KJM @@ -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 } - - - diff --git a/cmd/parse_line_test.go b/cmd/parse_line_test.go index 71f5426..f8ef6b0 100644 --- a/cmd/parse_line_test.go +++ b/cmd/parse_line_test.go @@ -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 ", 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 ", 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 ", - 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 ", + 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 ", - 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 ", + 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) { } }) } -} \ No newline at end of file +} diff --git a/cmd/root.go b/cmd/root.go index 58d7864..cdb5707 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,4 +1,5 @@ package cmd + /* Copyright © 2020 Jean-Marc Meessen, ON4KJM @@ -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) { }, diff --git a/cmd/validate.go b/cmd/validate.go index 4cf3597..5e43cca 100644 --- a/cmd/validate.go +++ b/cmd/validate.go @@ -1,4 +1,5 @@ package cmd + /* Copyright © 2020 Jean-Marc Meessen, ON4KJM @@ -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 }