; --------------------------------------------------------------------------------
; @Title: Veneer script for the TRACE32 software updater
; @Description:
;   The TRACE32 software updater (t32updater.exe) updates a complete TRACE32
;   installation to its latest release via the internet.
;   It is recommended to start the updater via this script, to inform the
;   TRACE32 software updater about the path to your T32 system directory and
;   your current software maintenance keys.
; @Author: HLG
; @Copyright: (C) 1989-2016 Lauterbach GmbH, licensed for use with TRACE32(R) only
; --------------------------------------------------------------------------------
; $Id: t32update.cmm 14989 2019-09-26 10:58:12Z hlohn $

PRIVATE &psd &ped &pwd &SILENT
PRIVATE &exe &PvInSys &t32update &maintenance

IF VERSION.BUILD()<32911.  // R.2011.06 (and later)
(
	GOSUB failed "Your copy of TRACE32 is too old (R.2011.06 or higher required)"
	ENDDO
)


GOSUB fixPath OS.PSD()
ENTRY %LINE &psd
&ped=OS.PED()
&pwd=OS.PWD()


&SILENT="SILENT."
IF VERSION.BUILD()<74028.
	&SILENT=""


IF OS.VERSION(0)<0x10
(
	&exe="\t32update.exe"
	&PvInSys=STRing.SCAN(STRing.UPpeR("&ped"),STRing.UPpeR("&(psd)\bin\"),0)==0
)
ELSE
(
	&exe="/t32update"
	&PvInSys=STRing.SCAN("&ped","&(psd)/bin/",0)==0
)


IF !&PvInSys
(
	GOSUB failed "This PowerView application is not located inside its TRACE32 system directory."
	ENDDO
)

IF OS.VERSION(0)==0x41
	&ped="&(psd)/bin/macosx64"  ; because actual executables are in "app"-subdirectories

&t32update="&ped&exe"
IF !OS.FILE("&t32update") // Updater not found ?
(
	IF (OS.VERSION(0)==0x10)||((OS.VERSION(0)==0x02)&&(SOFTWARE.64BIT())) // Updater not found on Linux (x86/x64) (or not found on Windows and running 64-bit version of PowerView) ?
	(
		// Can't find TRACE32 updater, thus let's try 32-bit instead of 64-bit version (and vice versa)
		IF SOFTWARE.64BIT()
			&ped=STRing.CUT("&ped",-2)
		ELSE
			&ped="&ped"+"64"
		IF OS.FILE("&ped&exe")
			&t32update="&ped&exe"
	)
)
IF !OS.FILE("&t32update") // Updater (still) not found ?
(
	GOSUB failed "because ""&t32update"" is missing"
	ENDDO
)
IF !OS.FILE.ACCESS("&t32update","x")
(
	GOSUB failed "No rights no execute ""&t32update"""
	ENDDO
)


&maintenance=""
IF VERSION.BUILD.BASE()>32167.  // R.2012.02 (and later)
(
	PRIVATE &i &sn &date &fmly
	&i=0.
	WHILE LICENSE.SERIAL(&i)!=""
	(
		&sn=LICENSE.SERIAL(&i)
		&date=LICENSE.DATE(&i)
		&fmly=LICENSE.FAMILY(&i)


		IF "&date"=="" // Old cables or FIRE without explicit programmed maintenance key?
		(
			// Make here a reluctant guess
			PRIVATE &y &m
			&y=STRing.MID(LICENSE.SERIAL(&i),1,2)+"."
			&m=STRing.MID(LICENSE.SERIAL(&i),3,2)
			IF &y>=90.
				&y=&y+1901.
			ELSE
				&y=&y+2001.
			&date=FORMAT.Decimal(4,&y)+"-&m"
		)
		ELSE
		(
			&date=STRing.MID("&date",0,4)+"-"+STRing.MID("&date",5,2)
		)

		IF "&fmly"==""
			&fmly="unknown"
		IF ("&fmly"=="unknown")&&(&i<3)
		(
			&fmly="unknown"
			PRIVATE &a &r &fm2 &sn2
			&a=&i*0x20
			&r="))+CONV.CHAR(BUS_EEREAD(&a+"
			&fm2=STRing.LoWeR(((""&r(0)&r(1)&r(2)&r(3))))
			&sn2=(("C"&r(4)&r(5)&r(6)&r(7)&r(8)&r(9)&r(10.)&r(11.)&r(12.)&r(13.)&r(14.)))
			IF "&sn2"=="&sn"
				&fmly="[&fm2]"
		)
		ELSE IF (VERSION.BUILD()>74993.)&&(STRing.CHAR("&fmly",0)==''')&&(STRing.CHAR("&fmly",STRing.LENgth("&fmly")-1)==''')  // Got only a four-letter code or hex-number ?
		(
			// TRACE32 > S.2016.07 returns a unknown generic code in single quotes for all unknown CPU architectures. (This code is either a hex-number or a four-letter code)
			&fmly="["+STRing.MID("&fmly",1,STRing.LENgth("&fmly")-2)+"]"  // replace single quotes by square brackets
		)

		IF STRing.CHAR("&fmly",0)=='['
		(
			// From the DebugCable a license was read, whose CPU family is unknown to the used version of TRACE32
			// => Translate IDs of non-confidential architectures into a nicer name:
			PRIVATE &i &str &id &fourcc
			Var.NEWLOCAL char[15][24] \family

			Var.Assign \family[0x00]="0x035|ubi |Ubicom32"
			Var.Assign \family[0x01]="0x037|spt |SPT"
			Var.Assign \family[0x02]="0x03A|apex|APEX"
			Var.Assign \family[0x03]="0x03B|arp |ARP32"
			Var.Assign \family[0x04]="0x03C|avr8|AVR8"
			Var.Assign \family[0x05]="0x03F|pru |PRU"
			Var.Assign \family[0x06]="0x03D|ipu |IPU"
			Var.Assign \family[0x07]="0x040|rscv|RISC-V"
			Var.Assign \family[0x08]="0x042|stm8|STM8"
			Var.Assign \family[0x09]="0x044|flux|CoolFlux"
			Var.Assign \family[0x0A]="0x045|strd|STRED"
			Var.Assign \family[0x0B]="0x046|esir|eSi-RISC"
			Var.Assign \family[0x0C]="0x048|pic |PIC"
			Var.Assign \family[0x0D]="0x049|meta|META"
			Var.Assign \family[0x0E]="0x050|7000|C7000"

			&i=Var.SIZEOF(\family)/Var.SIZEOF(\family[0])-1.
			WHILE &i>=0
			(
				&str=Var.STRing(\family[&i]);
				&id=STRing.MID("&str",0,5)
				&fourcc=STRing.TRIM(STRing.MID("&str",6,4))
				IF ("&fmly"=="[&id]")||("&fmly"=="[&fourcc]")
					&fmly=STRing.CUT("&str",11.)
				&i=&i-1
			)
			IF STRing.MID("&fmly",0,3)=="[0x"
				&fmly="[CPU "+STRing.CUT("&fmly",1)
		)

		IF VERSION.BUILD()>39758.  // R.2012.08 (and later)
		(
			// replace possible quotes or colons from family name
			&fmly=STRing.Replace("&fmly","""",".",0)
			&fmly=STRing.Replace("&fmly","'",".",0)
			&fmly=STRing.Replace("&fmly",":",".",0)
			&fmly=STRing.Replace("&fmly"," ","_",0)
		)
		ELSE
		(
			PRIVATE &j &c
			&j=0
			WHILE &j<STRing.LENgth("&fmly")
			(
				&c=STRing.CHAR("&fmly",&j)
				IF (&c=='"')||(&c==':')||(&c==''')
					&fmly=STRing.MID("&fmly",0,&j)+"."+STRing.CUT("&fmly",&j+1)
				IF (&c==' ')
					&fmly=STRing.MID("&fmly",0,&j)+"_"+STRing.CUT("&fmly",&j+1)
				&j=&j+1
			)
		)

		&maintenance="&maintenance --maintenance-license=""&sn:&date:&fmly"""
		&i=&i+1.
	)

)

&(SILENT)CD "&ped"  // Workaround, to ensure that updater can update itself
IF (OS.VERSION(0)<0x10)||(VERSION.BUILD.BASE()>65970.) // We have a non-blocking OS.screen command ?
(
	// t32update.exe --t32sys="C:/T32" --maintenance-license="C12090512454:2015-10:ARM"
	OS.screen  "&t32update" --t32sys="&psd" &maintenance
)
ELSE
(
	OS.Command "&t32update" --t32sys="&psd" &maintenance &
)
IF (OS.VERSION(0)>=0x10)&&(OS.VERSION(0)<0x40)
(
	WAIT 100.ms
	OS.Hidden ps cx | grep t32update
	IF (OS.RETURN()!=0)&&(OS.VERSION(0)<=0x11) // Failed to launch TRACE32 updater on Linux (x86/x64) ?
	(
		// Failed to launch TRACE32 updater on Linux, thus let's try 32-bit instead of 64-bit version (and vice versa)
		PRIVATE &pedAlt &t32updateAlt
		IF SOFTWARE.64BIT()
			&pedAlt=STRing.CUT("&ped",-2)
		ELSE
			&pedAlt="&ped"+"64"
		&t32updateAlt="&pedAlt&exe"
		IF (OS.FILE("&t32updateAlt"))&&(OS.FILE.ACCESS("&t32updateAlt","x"))
		(
			&(SILENT)CD "&pedAlt"
			OS.Command "&t32updateAlt" --t32sys="&psd" &maintenance &
			WAIT 100.ms
			OS.Hidden ps cx | grep t32update
		)
	)
	IF OS.RETURN()!=0
	(
		WinPOS ,,,,,,,,"Failed to launch TRACE32 updater"
		DIALOG.OK "Failed to launch executable t32update!" "Please launch ""&t32update"" from an OS command shell to check for some error messages (e.g. missing libraries)"
	)
)
&(SILENT)CD "&pwd"
ENDDO


fixPath:
	PRIVATE     &path
	ENTRY %LINE &path
	&path=&path

	IF OS.VERSION(0)<0x10
	(
		IF VERSION.BUILD()>=39759.
		(
			&path=STRing.Replace("&path","/","\",0)
		)
		ELSE
		(
			PRIVATE &len &i
			&len=STRing.LENgth("&path");
			&i=0.
			WHILE &i<&len
			(
				IF STRing.CHAR("&path",&i)=='/'
					&path=STRing.MID("&path",0,&i)+"\"+STRing.MID("&path",&i+1,&len-&i)
				&i=&i+1.
			)
		)
		IF STRing.CHAR("&path",1)==':'
			&path=STRing.UPpeR(STRing.MID("&path",0,1))+STRing.CUT("&path",1)
		IF STRing.CHAR("&path",STRing.LENgth("&path")-1)=='\'
			&path=STRing.CUT("&path",-1);
	)
	ELSE
	(
		IF STRing.CHAR("&path",STRing.LENgth("&path")-1)=='/'
			&path=STRing.CUT("&path",-1);
	)
	RETURN &path


failed:
	PRIVATE &txt1 &txt2 &txt3 &link &launch
	ENTRY   %LINE &txt2

	&txt1="No automatic update of TRACE32 possible!"
	&txt2="("+&txt2+")"
	&txt3="Please download the latest version of TRACE32 at"
	&link="https://www.lauterbach.com/7373"
	WinPOS ,,,,,,,"TRACE32 Update"
	IF (VERSION.BUILD()>45140.)&&(OS.VERSION(0)<0x20)
	(
		IF OS.VERSION(0)<0x10
			&launch="OS.Hidden start """""""""
		ELSE
			&launch="OS.screen xdg-open"
		DIALOG.view
		(&+
			POS 1. 0.5 50. 1.5
			TEXT "&txt1"
			POS 1. 1.5 50. 1.5
			TEXT "&txt2"
			POS 1. 3.5 50. 1.
			TEXT "&txt3"
			POS 1. 4.5 39. 1.
			TEXTBUTTON ""+CONVert.CHAR(2)+CONVert.CHAR(76.+1.)+"&link" "&launch &link"

			POS 41. 5.0 9. 1.
			DEFBUTTON "OK" "DIALOG.END"
		)
	)
	ELSE
	(
		DIALOG.OK "&txt1" "&txt2" "" "&txt3 &link"
	)
	RETURN
