Files
Gen4_R-Car_Trace32/2_Trunk/demo/practice/lib.cmm
2025-10-14 09:52:32 +09:00

429 lines
13 KiB
Plaintext

; --------------------------------------------------------------------------------
; @Title: Collection of some helper functions
; @Description:
; This script is a collection of some helper functions for your
; daily work with the PRACTICE script language.
;
; You can call these functions with
; DO ~~/demo/practice/lib.cmm <FUNCTION> <ARGUMENTS>
;
; @Keywords: PRACTICE
; @Author: HLG
; @Copyright: (C) 1989-2019 Lauterbach GmbH, licensed for use with TRACE32(R) only
; --------------------------------------------------------------------------------
; $Id: lib.cmm 14936 2019-09-16 11:25:18Z hlohn $
LOCAL &func &arg &result
ENTRY &func %line &arg
ON ERROR GOTO
(
LOCAL &ppf
&ppf=OS.PPF()
PRINT %ERROR "Sorry, '"+OS.FILE.NAME("&ppf")+"' doesn't know function '&func'"
STOP
)
&func=STRING.UPR("&func")
GOSUB &func &arg
ENTRY %LINE &result
ENDDO &result
////////////////////////////////////////////////////////////////////////////////////////////
VERSION:
// Returns the version number of this PRACTICE library
// and sets global macro &libver, which contains the version number, too.
// Syntax:
// DO lib.cmm VERSION
// Returns:
// The version number of this file
// Example:
// DO ~~/demo/practice/lib.cmm VERSION
// PRINT "lib.cmm is version " %Decimal &libver "."
ON ERROR NOTHING
GLOBAL &libver
&libver=STRing.CUT(STRing.CUT("$Rev: 14936 $",6),-2)+"."
RETURN &libver
////////////////////////////////////////////////////////////////////////////////////////////
OPENNEW:
// Opens a file just like OPEN but seaches for an unused 'bufferno'
// Syntax:
// DO lib.cmm OPENNEW <filename> [<option>]
// Returns:
// The file 'bufferno' e.g.: #42
// Example:
// LOCAL &logfile
// DO ~~/demo/practice/lib.cmm OPENNEW ~~~~/log.txt /Append
// ENTRY &logfile
// WRITE &logfile "new event!"
// CLOSE &logfile
ON ERROR NOTHING
LOCAL &arg &fn
ENTRY %line &arg
&fn=1
IF VERSION.BUILD()>31360. // function FILE.EOF exists ? (2011-07-27)
(
IF VERSION.BUILD.BASE()>36377. // function FILE.OPEN exists ? (2012-04-22)
(
WHILE {FILE.OPEN(&fn)}&&{&fn<120.}
&fn=&fn+1
)
ELSE
(
ON ERROR GOTO break
WHILE &fn<120.
(
EVAL FILE.EOF(&fn) // results in error if file number is not open
&fn=&fn+1
)
break:
)
)
ELSE
(
&fn=(RANDOM()&0xFF)%100.+20. // take random number between 20 and the maximum of 119.
PRINT %ERROR "TRACE32 too old to use OPENNEW (build 31361. or higher required)"
STOP
)
&fn="#"+FORMAT.Decimal(0,&fn)
OPEN &fn &arg
RETURN &fn
////////////////////////////////////////////////////////////////////////////////////////////
SIZOFMAU:
// Detects the width of the mimimal adressable unit (MAU) in the VM memory space (Data.dump VM:0)
// Syntax:
// DO lib.cmm SIZOFMAU
// Returns:
// Width of one adressable unit in the VM memory space in bytes
// Example:
// LOCAL &width
// DO ~~/demo/practice/lib.cmm SIZOFMAU
// ENTRY &width
// PRINT "Width is " %Decimal &width "Bytes"
ON ERROR NOTHING
LOCAL &tfile &width &memclass
&tfile=OS.TMPFILE()
ON ERROR GOSUB
(
LOCAL &err
&err=HELP.MESSAGE()
ON ERROR NOTHING
IF "&err"=="#emu_errvmnotval" // Error VM not valid ?
(
Data.Set VM:0--8 %Byte 0
Data.SAVE.Binary "&tfile" VM:0--8
)
ELSE
(
STOP // unexpected error occurred
)
RETURN
)
Data.SAVE.Binary "&tfile" VM:0--8
ON ERROR NOTHING
Data.Set vm:0 %Byte 0 1 2 3 4 5 6 7 8
&width=Data.Byte(VM:1)
Data.LOAD.Binary "&tfile" VM:0--8
RM "&tfile"
RETURN &width
////////////////////////////////////////////////////////////////////////////////////////////
FIXNUM:
// Ensures that all passed macros contain an expression which expands to a number
// or sets the value to zero otherwise
// Syntax:
// DO lib.cmm FIXNUM &arg1 [&arg2] [&arg3] [...&argN]
// Returns:
// returns the fixed versions of &arg1 [&arg2] [&arg3] [...&argN]
// Example:
// LOCAL &v1 &v2 &v3
// ENTRY &v1 &v2 &v3
// DO ~~/demo/practice/lib.cmm FIXNUM &v1 &v2 &v3
// ENTRY &v1 &v2 &v3
//
// PRINT "&v1 &v2 &v3"
// ENDDO
ON ERROR NOTHING
LOCAL &num &rest &val
ENTRY &num %LINE &rest
&val="&num"
ON ERROR GOSUB
(
EVAL 1==1
RETURN
)
EVAL &num // if &num is a string without quotes it will be interpreted as sYmbol, which will probably result in "symbol not found" error
ON ERROR NOTHING
IF (EVAL.TYPE()&{0x3E})==0 // bin,hex,dec,ascii or float ?
(
&val=0
)
IF "&rest"!=""
(
LOCAL &tmp
GOSUB FIXNUM &rest
ENTRY %LINE &tmp
&val="&val &tmp"
)
RETURN &val
////////////////////////////////////////////////////////////////////////////////////////////
T32BUILDNUM:
// Sets two GLOBAL variables &t32_Build &t32_BuildBase
// which get set to VERSION.BUILD() and VERSION.BUILD.BASE() if possible
// Syntax:
// DO lib.cmm T32BUILDNUM
// Returns:
// none
// Example:
// DO ~~/demo/practice/lib.cmm T32BUILDNUM
// IF &t32_Build==&t32_BuildBase
// PRINT "This is TRACE32 interim build " %Decimal &t32_Build "."
// ELSE
// PRINT "This is TRACE32 release build " %Decimal &t32_BuildBase "--" %Decimal &t32_Build "."
ON ERROR NOTHING
GLOBAL &t32_Build &t32_BuildBase
&t32_Build=VERSION.BUILD()
&t32_BuildBase=VERSION.BUILD()
IF VERSION.BUILD()>15282. // (2008-09-26)
&t32_BuildBase=VERSION.BUILD.BASE()
RETURN
////////////////////////////////////////////////////////////////////////////////////////////
ENTERDLG:
// Opens a dialog box which asks a user for some input data.
// This should be an alternative to the ENTER command
// Syntax:
// DO lib.cmm ENTERDLG "<question>" ["<window-header>"]
// Returns:
// The input data (without quotes!)
// Example:
// LOCAL &name
// DO ~~/demo/practice/lib.cmm ENTERDLG "What's your name?" "Identification"
// ENTRY %LINE &name
// PRINT "Hello &name!"
ON ERROR NOTHING
LOCAL &question &header
ENTRY &question &header
&question=&question
&header=&header
IF "&header"==""
&header="Input"
LOCAL &name
DIALOG
(&+
HEADER "&header"
POS 0.5 0.5 20.5 1.
TEXT "&question"
POS 0.5 2. 20. 1.
ENTERDLG_input: DEFEDIT "" ""
POS 6.5 3.5 8. 1.
DEFBUTTON "OK" "CONTinue"
CLOSE ""
)
STOP
&name=DIALOG.STRING(ENTERDLG_input)
DIALOG.END
RETURN &name
////////////////////////////////////////////////////////////////////////////////////////////
OPENURL:
// Opens a web browser to display the given URL (optional with your favorite browser)
// Works only on Windows!
// In contrast to a simple "OS.Command start <URL>" you can also pass GET-parameters
// or open local URL which is not of type *.htm/*.html
// Syntax:
// DO lib.cmm OPENURL "<URL>" [firefox|opera|chrome|iexplore]
// Example:
// DO ~~/demo/practice/lib.cmm OPENURL "example.xml?mode=hll"
ON ERROR NOTHING
LOCAL &url &browser
ENTRY &url &browser
IF (VERSION.BUILD()>=112151.)&&("&browser"==""||OS.VERSION(0)>=0x10)
(
IF (STRing.CHAR("&url",0)=='"')&&(STRing.CHAR("&url",STRING.LENgth("&url")-1)=='"')
&url=&url
OS.OPEN "&url"
RETURN
)
IF OS.VERSION(0)>=0x10 // not Windows
RETURN
IF STRing.CHAR("&url",0)=='"'
&url=&url
IF STRing.SCAN("&url","://",0)<0 ;no URL scheme ?
(
IF STRing.SCAN("&url","~~~/",0)==0
&url=OS.PTD()+"/"+STRing.CUT("&url",4)
IF STRing.SCAN("&url","~~/",0)==0
&url=OS.PSD()+"/"+STRing.CUT("&url",3)
IF STRing.SCAN("&url","~/",0)==0
&url=OS.PHD()+"/"+STRing.CUT("&url",2)
IF STRing.CHAR("&url",1)!=':'
&url=OS.PWD()+"/&url"
&url= "file:///&url"
)
IF VERSION.BUILD()>39758.
(
&url=STRing.Replace("&url","\","/",0)
&url=STRing.Replace("&url","%","%25",0)
&url=STRing.Replace("&url","+","%2B",0)
&url=STRing.Replace("&url"," ","%20",0)
)
LOCAL &prog1 &prog2 &rapp &lapp
&prog1=OS.ENV(PROGRAMFILES)
&prog2="C:/Program Files (x86)"
&lapp=OS.ENV(LOCALAPPDATA)
IF "&localappdata"=="" ; Win XP ?
(
&rapp=OS.ENV(APPDATA)
&localappdata="&rapp/../Local Settings/Application Data"
IF OS.DIR("&rapp/../Lokale Einstellungen/Anwendungsdaten")
&localappdata="&rapp/../Lokale Einstellungen/Anwendungsdaten"
)
LOCAL &haveFirefox &haveOpera &haveChrome &havePresto
&haveFirefox=OS.FILE("&prog1/Mozilla Firefox/firefox.exe")||OS.FILE("&prog2/Mozilla Firefox/firefox.exe")
&haveChrome=OS.FILE("&lapp/Google/Chrome/Application/chrome.exe")||OS.FILE("&prog1/Google/Chrome/Application/chrome.exe")||OS.FILE("&prog2/Google/Chrome/Application/chrome.exe")
&havePresto=OS.FILE("&prog1/Opera/opera.exe")||OS.FILE("&prog2/Opera/opera.exe") // Opera 12.17 and older (with Presto rendering engine)
&haveOpera=OS.FILE("&prog1/Opera/launcher.exe")||OS.FILE("&prog2/Opera/launcher.exe")
&browser=STRing.LWR("&browser")
IF !(&haveFirefox||&haveChrome||&haveOpera)&&("&browser"!="iexplore")
&browser=""
IF (&haveOpera)&&(("&browser"=="opera")||("&browser"=="")) // Opera >= 15
&browser="opera --allow-file-access-from-files"
ELSE IF (&havePresto)&&(("&browser"=="opera")||("&browser"=="")) // Opera <= 12.17
&browser="opera"
ELSE IF (&haveChrome)&&(("&browser"=="chrome")||("&browser"==""))
&browser="chrome --allow-file-access-from-files"
ELSE IF (&haveFirefox)&&(("&browser"=="firefox")||("&browser"==""))
&browser="firefox"
ELSE
&browser="iexplore"
OS.Command start &browser "&url"
RETURN
////////////////////////////////////////////////////////////////////////////////////////////
CREATE_ENUM:
// Helps to create MACRO definitions of enumeration lists easily
// If in your target application, the names for values of variables are not defined
// with enumerations (enum) but with preprocessor macros, you won't see
// the names during debugging since preprocessor macros are not part of the
// debug information of your ELF file
// With this routine you can easily add the missing definitions.
// Syntax:
// DO lib.cmm CREATE_ENUM <enumlist> [variable1] [variable2] [...variableN]
// <enumlist> must be a string containing a comma separated list of key-value pairs, which
// describe the enumeration list
// Returns:
// void
// Example:
// LOCAL &sailors
// &sailors="SAILOR_NIX=0,SAILOR_JAN=1,SAILOR_HEIN=2,SAILOR_KLAAS=300,SAILOR_PIT=0x400"
// DO ~~/demo/practice/lib.cmm CREATE_ENUM "&sailors" mcount mstatic1
// Var.AddWatch mcount mstatic1
// Var.Set mcount=SAILOR_KLAAS
// DO ~~/demo/practice/lib.cmm CREATE_ENUM "JOHN,PAUL,GEORGE,RINGO"
// DO ~~/demo/practice/lib.cmm CREATE_ENUM "ONE,TWO,THREE,FIFE=5,SIX"
ON ERROR NOTHING
LOCAL &enumlist &variables &varlist &x3 &last
ENTRY &enumlist %line &variables
IF STRing.CHAR("&enumlist",0)=='"'
&enumlist=&enumlist
&last=-1.
&varlist="&variables"
WHILE "&varlist"!=""
(
&x3=STRing.SCAN("&varlist"," ",0)
IF &x3<0
&x3=STRing.LENgth("&varlist")
&var=STRing.MID("&varlist",0,&x3)
&varlist=STRing.CUT("&varlist",&x3+1)
sYmbol.AddInfo.Delete &var
)
WHILE "&enumlist"!=""
(
LOCAL &x1 &x2 &key &val &var
&x1=STRing.SCAN("&enumlist","=",0)
&x2=STRing.SCAN("&enumlist",",",0)
IF &x2<0
&x2=STRing.LENgth("&enumlist")
IF (&x1>&x2)||(&x1<0)
&x1=&x2
&key=STRing.TRIM(STRing.MID("&enumlist",0,&x1))
&val=STRing.TRIM(STRing.MID("&enumlist",&x1+1,&x2-&x1-1))
IF "&val"==""
&val=FORMAT.Decimal(0,&last+1)
&enumlist=STRing.CUT("&enumlist",&x2+1)
sYmbol.CREATE.MACRO &key &val
if STRing.MID(STRing.LoWeR("&val"),0,2)!="0x"
&val="0x"+FORMAT.HEX(0,&val.)
&varlist="&variables"
WHILE "&varlist"!=""
(
&x3=STRing.SCAN("&varlist"," ",0)
if &x3<0
&x3=STRing.LENgth("&varlist")
&var=STRing.MID("&varlist",0,&x3)
&varlist=STRing.CUT("&varlist",&x3+1)
sYmbol.AddInfo.Var &var ENUM &val "&key"
)
&last=&val
)
sYmbol.CREATE.Done
RETURN
////////////////////////////////////////////////////////////////////////////////////////////
INIT_ARRAY:
// Helps to initialize HLL arrays easily
// Syntax:
// DO lib.cmm INIT_ARRAY <name-of-array> <init-values>
// <enumlist> must are a comma separated list of values which should be
// assigned to the array
// Returns:
// void
// Examples:
// Var.NEWLOCAL int[6] \arr1 ; create new "artificial" array called \arr1
// DO ~~/demo/practice/lib.cmm INIT_ARRAY \arr1 0,1,2, 3, 4,5 ; initialize array
// Var.View %STanDard %Decimal %Index %Open.1 \arr1 ; show result
//
// Var.NEWLOCAL char[8][10] \arr2
// DO ~~/demo/practice/lib.cmm INIT_ARRAY \arr2 "no one","Jan","Hein","Klaas", "Pit"
// Var.View %STanDard %String %Index %Open.1 \arr2
ON ERROR NOTHING
LOCAL &var &args &val &x &idx
ENTRY &var %LINE &args
&idx=0
&x=STRing.SCAN("&args",",",0)
WHILE &x>0
(
&val=STRing.TRIM(STRing.MID("&args",0,&x))
&args=STRing.CUT("&args",&x+1)
Var.set (&var)[&idx]=&val
&idx=&idx+1
&x=STRing.SCAN("&args",",",0)
)
&val=STRing.TRIM("&args")
IF "&val"!=""
Var.set (&var)[&idx]=&val
RETURN
////////////////////////////////////////////////////////////////////////////////////////////