Skip to content

Commit

Permalink
CLI switch -IDRange added, emitter "channels" renamed to "tags"
Browse files Browse the repository at this point in the history
  • Loading branch information
rokath committed Oct 14, 2024
1 parent ef626e2 commit 566d436
Show file tree
Hide file tree
Showing 12 changed files with 262 additions and 111 deletions.
4 changes: 4 additions & 0 deletions internal/args/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ func Handler(w io.Writer, fSys *afero.Afero, args []string) error {
case "i", "insert":
msg.OnErr(fsScInsert.Parse(subArgs))
id.CompactSrcs()
err := id.EvaluateIDRangeStrings()
if err != nil {
return err
}
w = do.DistributeArgs(w, fSys, LogfileName, Verbose)
return id.SubCmdIdInsert(w, fSys)
// // case "zeroSourceTreeIds":
Expand Down
6 changes: 3 additions & 3 deletions internal/args/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,9 @@ func addInit() {
// }

func insertIDsInit() {
fsScInsert = flag.NewFlagSet("insertSourceTreeIds", flag.ExitOnError) // sub-command
fsScInsert = flag.NewFlagSet("insert", flag.ExitOnError) // sub-command
flagsRefreshAndUpdate(fsScInsert)
// todo: flagTriceIDRange(fsScInsert)
flagTriceIDRange(fsScInsert)
fsScInsert.Var(&id.Min, "IDMin", "Lower end of ID range for normal trices.")
fsScInsert.Var(&id.Max, "IDMax", "Upper end of ID range for normal trices.")
fsScInsert.IntVar(&id.DefaultStampSize, "defaultStampSize", 32, "Default stamp size for written TRICE macros without id(0), Id(0 or ID(0). Valid values are 0, 16 or 32.")
Expand Down Expand Up @@ -246,7 +246,7 @@ func scanInit() {
}

func sdInit() {
fsScSdSv = flag.NewFlagSet("shutdownServer", flag.ExitOnError) // sub-command
fsScSdSv = flag.NewFlagSet("shutdown", flag.ExitOnError) // sub-command
flagIPAddress(fsScSdSv)
}

Expand Down
15 changes: 0 additions & 15 deletions internal/args/short_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,6 @@ import (
"github.com/tj/assert"
)

// func TestMain(m *testing.M) {
// id.FnJSON = getTemporaryFileName("til-*.JSON")
// code := m.Run()
// msg.OnErr(os.Remove(id.FnJSON))
// os.Exit(code) // os.Exit() does not respect defer statements
// }

func getTemporaryFileName(pattern string) string {
tempFileHandle, e := os.CreateTemp(os.TempDir(), pattern) // opens for read and write
msg.OnErr(e)
tempFileName := tempFileHandle.Name()
msg.OnErr(tempFileHandle.Close())
return tempFileName
}

func TestHelp(t *testing.T) {
args := []string{"trice", "help"}
expect := `syntax: 'trice sub-command' [params]
Expand Down
13 changes: 11 additions & 2 deletions internal/args/tricehelpall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,15 @@ sub-command 'i|insert': For updating til.json and inserting IDs into source file
Search method for new ID's in range- Options are 'upward', 'downward' & 'random'. (default "random")
-IDMin value
Lower end of ID range for normal trices. (default 1000)
-IDRange value
This allows channel specific routing in the target code.
This switch has one parameter string and is a multi-flag switch. It can be used for each Trice tag. Example:
Assign error tag Trice IDs in the range 10-99 and msg tag IDs in the range 100-199:
"trice insert -IDRange err:10,99 -IDRange msg:100,999" (overlapping ID ranges are forbidden)
All other trice tags get IDs from the -IDMin, -IDMax range. The used -IDMethod is the same for all tags.
For example you can have all trice messages in direct mode over RTT but err & msg tagged trices additionally
in deferred mode over a serial port and, if you need, store all error tagged Trice logs additionally in the Flash memory.
You need to configure the target code accordingly. (default "")
-addParamCount
Extend TRICE macro names with the parameter count _n to enable compile time checks.
-cache
Expand All @@ -404,7 +413,7 @@ sub-command 'i|insert': For updating til.json and inserting IDs into source file
Default stamp size for written TRICE macros without id(0), Id(0 or ID(0). Valid values are 0, 16 or 32. (default 32)
-dry-run
No changes applied but output shows what would happen.
"trice insertSourceTreeIds -dry-run" will change nothing but show changes it would perform without the "-dry-run" switch.
"trice insert -dry-run" will change nothing but show changes it would perform without the "-dry-run" switch.
This is a bool switch. It has no parameters. Its default value is false. If the switch is applied its value is true. You can also set it explicit: =false or =true.
-i string
Short for '-idlist'.
Expand Down Expand Up @@ -444,7 +453,7 @@ sub-command 'i|insert': For updating til.json and inserting IDs into source file
-src value
Source dir or file, It has one parameter. Not usable in the form "-src *.c".
This is a multi-flag switch. It can be used several times for directories and also for files.
Example: "trice insertSourceTreeIds -dry-run -v -src ./test/ -src pkg/src/trice.h" will scan all C|C++ header and
Example: "trice insert -dry-run -v -src ./test/ -src pkg/src/trice.h" will scan all C|C++ header and
source code files inside directory ./test and scan also file trice.h inside pkg/src directory.
Without the "-dry-run" switch it would create|extend a list file til.json in the current directory.
(default "./")
Expand Down
2 changes: 1 addition & 1 deletion internal/emitter/emitter.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func appendIfMissing(slice []string, i string) []string {
func (i *channelArrayFlag) Set(value string) error {
ss := strings.Split(value, ":")
for _, s := range ss {
cv := channelVariants(s)
cv := tagVariants(s)
for _, c := range cv {
*i = appendIfMissing(*i, c)
}
Expand Down
103 changes: 58 additions & 45 deletions internal/emitter/lineTransformerANSI.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,64 +97,77 @@ func isLower(s string) bool {
return true
}

type colorChannel struct {
events int
channel []string
colorize func(string) string
type tag struct {
count int // count counts each occurance of the trice tag.
Names []string // name contains all usable names fo a specific tag.
colorize func(string) string // colorize is the function called for each tag.
}

var colorChannels = []colorChannel{
// Tags contains all usable trice Tags and their possible names.
var Tags = []tag{
// log level
{0, []string{"Fatal", "fatal", "FATAL"}, colorizeFATAL},
{0, []string{"Critical", "critical", "CRITICAL", "crit", "Crit", "CRIT"}, colorizeCRITICAL},
{0, []string{"Emergency", "emergency", "EMERGENCY"}, colorizeEMERGENCY},
{0, []string{"Error", "e", "err", "error", "E", "ERR", "ERROR"}, colorizeERROR},
{0, []string{"Warning", "w", "wrn", "warning", "W", "WRN", "WARNING", "Warn", "warn", "WARN"}, colorizeWARNING},
{0, []string{"crit", "Critical", "critical", "CRITICAL", "Crit", "CRIT"}, colorizeCRITICAL},
{0, []string{"em", "Emergency", "emergency", "EMERGENCY"}, colorizeEMERGENCY},
{0, []string{"e", "Error", "err", "error", "E", "ERR", "ERROR"}, colorizeERROR},
{0, []string{"w", "wrn", "Warning", "warning", "W", "WRN", "WARNING", "Warn", "warn", "WARN"}, colorizeWARNING},
{0, []string{"att", "attention", "Attention", "ATT", "ATTENTION"}, colorizeATTENTION},
{0, []string{"Info", "i", "inf", "info", "informal", "I", "INF", "INFO", "INFORMAL"}, colorizeINFO},
{0, []string{"Debug", "d", "db", "dbg", "deb", "debug", "D", "DB", "DBG", "DEBUG"}, colorizeDEBUG},
{0, []string{"Trace", "trace", "TRACE"}, colorizeTRACE},
{0, []string{"i", "inf", "info", "Info", "informal", "I", "INF", "INFO", "INFORMAL"}, colorizeINFO},
{0, []string{"d", "db", "Debug", "dbg", "deb", "debug", "D", "DB", "DBG", "DEBUG"}, colorizeDEBUG},
{0, []string{"tr", "Trace", "trace", "TRACE"}, colorizeTRACE},

// user modes
{0, []string{"Timestamp", "tim", "time", "TIM", "TIME", "TIMESTAMP", "timestamp"}, colorizeTIME},
{0, []string{"tim", "time", "TIM", "TIME", "TIMESTAMP", "timestamp", "Timestamp"}, colorizeTIME},
{0, []string{"m", "msg", "message", "M", "MSG", "MESSAGE", "OK"}, colorizeMESSAGE},
{0, []string{"r", "rx", "rd", "read", "rd_", "RD", "RD_", "READ"}, colorizeREAD},
{0, []string{"w", "tx", "wr", "write", "wr_", "WR", "WR_", "WRITE"}, colorizeWRITE},
{0, []string{"receive", "rx", "RECEIVE", "Receive", "RX"}, colorizeRECEIVE},
{0, []string{"transmit", "tx", "TRANSMIT", "Transmit", "TX"}, colorizeTRANSMIT},
{0, []string{"rx", "receive", "RECEIVE", "Receive", "RX"}, colorizeRECEIVE},
{0, []string{"tx", "transmit", "TRANSMIT", "Transmit", "TX"}, colorizeTRANSMIT},
{0, []string{"dia", "diag", "Diag", "DIA", "DIAG"}, colorizeDIAG},
{0, []string{"int", "isr", "ISR", "INT", "interrupt", "Interrupt", "INTERRUPT"}, colorizeINTERRUPT},
{0, []string{"s", "sig", "signal", "S", "SIG", "SIGNAL"}, colorizeSIGNAL},
{0, []string{"t", "tst", "test", "T", "TST", "TEST"}, colorizeTEST},

{0, []string{"Default", "DEFAULT", "default"}, colorizeDEFAULT},
{0, []string{"Notice", "NOTICE", "notice", "Note", "note", "NOTE"}, colorizeNOTICE},
{0, []string{"def", "Default", "DEFAULT", "default"}, colorizeDEFAULT},
{0, []string{"note", "Notice", "NOTICE", "notice", "Note", "NOTE"}, colorizeNOTICE},
{0, []string{"Alert", "alert", "ALERT"}, colorizeALERT},
{0, []string{"Assert", "assert", "ASSERT"}, colorizeASSERT},
{0, []string{"Alarm", "alarm", "ALARM"}, colorizeALARM},
{0, []string{"cycle", "CYCLE"}, colorizeCYCLE},
{0, []string{"Verbose", "verbose", "VERBOSE"}, colorizeVERBOSE},
{0, []string{"a", "Alarm", "alarm", "ALARM"}, colorizeALARM},
{0, []string{"cy", "cycle", "CYCLE"}, colorizeCYCLE},
{0, []string{"v", "Verbose", "verbose", "VERBOSE"}, colorizeVERBOSE},
}

// ColorChannelEvents returns count of occurred channel events.
func FindTagName(name string) (tagName string, err error) {
for _, t := range Tags {
for _, tn := range t.Names {
if tn == name {
tagName = t.Names[0] // take the first tag name as reference.
return
}
}
}
return "", fmt.Errorf("no tagName found for name %s", name)
}

// TagEvents returns count of occurred channel events.
// If ch is unknown, the returned value is -1.
func ColorChannelEvents(ch string) int {
for _, s := range colorChannels {
for _, c := range s.channel {
func TagEvents(ch string) int {
for _, s := range Tags {
for _, c := range s.Names {
if c == ch {
return s.events
return s.count
}
}
}
return -1
}

// PrintColorChannelEvents shows the amount of occurred channel events.
func PrintColorChannelEvents(w io.Writer) {
for _, s := range colorChannels {
if s.events != 0 {
fmt.Fprintf(w, "%6d times: ", s.events)
for _, c := range s.channel {
// PrintTagEvents shows the amount of occurred channel events.
func PrintTagEvents(w io.Writer) {
for _, s := range Tags {
if s.count != 0 {
fmt.Fprintf(w, "%6d times: ", s.count)
for _, c := range s.Names {
if ColorPalette != "off" && ColorPalette != "none" {
c = s.colorize(c)
}
Expand All @@ -165,22 +178,22 @@ func PrintColorChannelEvents(w io.Writer) {
}
}

// channelVariants returns all variants of ch as string slice.
// tagVariants returns all variants of ch as string slice.
// If ch is not inside ansiSel nil is returned.
func channelVariants(ch string) []string {
for _, s := range colorChannels {
for _, c := range s.channel {
func tagVariants(ch string) []string {
for _, s := range Tags {
for _, c := range s.Names {
if c == ch {
return s.channel
return s.Names
}
}
}
return nil
}

// isChannel returns true if ch is any ansiSel string.
func isChannel(ch string) bool {
cv := channelVariants(ch)
// isTag returns true if tag is any tag variant string.
func isTag(tag string) bool {
cv := tagVariants(tag)
return cv != nil
}

Expand All @@ -203,10 +216,10 @@ func (p *lineTransformerANSI) colorize(s string) (r string, show bool) {
if len(sc) < 2 { // no color separator (no log level)
return r, true // do nothing, return unchanged string
}
for i, cc := range colorChannels {
for _, c := range cc.channel {
for i, cc := range Tags {
for _, c := range cc.Names {
if c == sc[0] {
colorChannels[i].events++ // count event
Tags[i].count++ // count event
logLev = i
}
if c == LogLevel {
Expand All @@ -223,14 +236,14 @@ func (p *lineTransformerANSI) colorize(s string) (r string, show bool) {
if p.colorPalette == "off" {
return r, true // do nothing (despite event counting)
}
if isChannel(sc[0]) && isLower(sc[0]) {
if isTag(sc[0]) && isLower(sc[0]) {
r = sc[1] // remove channel info
}
if p.colorPalette == "none" {
return r, true
}
for _, cs := range colorChannels {
for _, c := range cs.channel {
for _, cs := range Tags {
for _, c := range cs.Names {
if c == sc[0] {
return cs.colorize(r), true
}
Expand Down
4 changes: 2 additions & 2 deletions internal/id/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"github.com/spf13/afero"
)

var SkipAdditionalChecks bool

// CompactSrcs adds local dir to Srcs if Srcs is empty and reduces variable Scrs to the minimum to address all intended folders.
func CompactSrcs() {
if len(Srcs) == 0 { // Srcs is an array flag containing desired folders & files
Expand All @@ -34,8 +36,6 @@ func CompactSrcs() {
Srcs = slices.Compact(Srcs)
}

var SkipAdditionalChecks bool

// fileExists returns true, if path exits.
func fileExists(fSys *afero.Afero, path string) bool {
if _, err := fSys.Stat(path); err == nil {
Expand Down
57 changes: 57 additions & 0 deletions internal/id/range_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2024 Thomas.Hoehenleitner [at] seerose.net
// Use of this source code is governed by a license that can be found in the LICENSE file.

package id_test

import (
"fmt"
"testing"

"github.com/rokath/trice/internal/args"
. "github.com/rokath/trice/internal/id"
"github.com/tj/assert"
)

// source tree management

func TestRange0(t *testing.T) {
defer Setup(t)()

// create src file
sFn := t.Name() + "file.c"
src := `trice("msg:Hi\n");trice("err:Alarm!\n");trice("msg:Lo\n");`
assert.Nil(t, FSys.WriteFile(sFn, []byte(src), 0777))

// action
assert.Nil(t, args.Handler(W, FSys, []string{"trice", "insert", "-IDMethod", "upward", "-src", sFn, "-til", FnJSON, "-li", LIFnJSON}))

// check modified src file
expSrc := `trice(iD(1000), "msg:Hi\n");trice(iD(1001), "err:Alarm!\n");trice(iD(1002), "msg:Lo\n");`

actSrc, e := FSys.ReadFile(sFn)
assert.Nil(t, e)

assert.Equal(t, expSrc, string(actSrc))
}

func TestRange1(t *testing.T) {
defer Setup(t)()

// create src file
sFn := t.Name() + "file.c"
src := `trice("msg:Hi\n"); ... trice("err:Alarm!\n"); ... trice("msg:Lo\n"); ... trice("dbg:foo\n");`
assert.Nil(t, FSys.WriteFile(sFn, []byte(src), 0777))

// action
assert.Nil(t, args.Handler(W, FSys, []string{"trice", "insert", "-IDRange", "e:100,109", "-IDRange", "dbg:200,209", "-IDMax=1005", "-IDMethod", "upward", "-src", sFn, "-til", FnJSON, "-li", LIFnJSON}))

fmt.Println(IDData.IDSpace)

// check modified src file
expSrc := `trice(iD(1000), "msg:Hi\n"); ... trice(iD(100), "err:Alarm!\n"); ... trice(iD(1001), "msg:Lo\n"); ... trice(iD(200), "dbg:foo\n");`

actSrc, e := FSys.ReadFile(sFn)
assert.Nil(t, e)

assert.Equal(t, expSrc, string(actSrc))
}
Loading

0 comments on commit 566d436

Please sign in to comment.