English Amiga Board


Go Back   English Amiga Board > Coders > Coders. System > Coders. Scripting

 
 
Thread Tools
Old 26 October 2021, 00:27   #1
malko
Ex nihilo nihil
 
malko's Avatar
 
Join Date: Oct 2017
Location: CH
Posts: 4,856
Lightbulb AmigaOS 1.3 ' strlng ' command

This time I needed to check the length of a given string (and no 1.3.3 built-in facility I am aware of...)

I have therefore created a script that call itself recursively. On this purpose a counter is incremented with the 'eval' command and with the help of the 'echo' command arguments, the string is recreated one character at a time until the full string is reached.

As you may understand, the longer the string, the longer the process... BUT it works . Oh, by the way, it's possible to input a string that has space(s).

Please mind that I have not implemented a test to check if the inputed string is empty. So an endless loop will happen if you simply press 'return' at the input prompt .

As usual, the result is stored and can be retrieved with the 'getenv' command. The Shell number is appended to the variable name so different 'strlng' commands can be run at the same time from different Shells.

If you have ideas to improve the process, thanks to let me know.

NEW VERSION OF THE SCRIPT AVAILABLE BELOW. SEE POST #4

Code:
strlng : 
.key STRING,COUNTER/K,STEP/K,STRTMP/K,SCRNM/K
.bra {
.ket }
.def STRING "-"
.def COUNTER -1
.def STEP 1
.def SCRNM "strlng"
if NOT "{STRING}" EQ "-"
    setenv >NIL: STRING{$$} "{STRING}"
    skip mlk0{STEP}
endif
if VAL {COUNTER} EQ -1
   echo "*N  *e[33mIf the string contains space(s),*e[0m"
    echo "  *e[33minput it with quotation marks.*e[0m    "
    echo "  What is your string ? " NOLINE
   setenv >NIL: STRING{$$} ?
endif
skip mlk0{STEP}
skip exit
lab mlk01
echo >t:rmvcr{$$} "1CL//*Nw"
echo >t:prep{$$} "execute {SCRNM} COUNTER 1 STEP 2 STRING *"" NOLINE
getenv >>t:prep{$$} STRING{$$}
echo >>t:prep{$$} "*""
edit FROM t:prep{$$} TO t:prep{$$}. WITH t:rmvcr{$$}
execute t:prep{$$}.
run >NIL: delete env:STRING{$$} t:prep{$$} t:prep{$$}. t:rmvcr{$$} QUIET
skip exit
lab mlk02
echo >t:interm{$$} "execute {SCRNM} STRING *"{STRING}*" STEP 3 STRTMP *"" NOLINE
echo >>t:interm{$$} "{STRING}" FIRST 1 LEN {COUNTER} NOLINE
echo >>t:interm{$$} "*" COUNTER " NOLINE
eval VALUE1 {COUNTER} OP + VALUE2 1 TO env:cpt{$$}
getenv >>t:interm{$$} cpt{$$}
execute t:interm{$$}
run >NIL: delete t:interm{$$} env:cpt{$$} QUIET
skip exit
lab mlk03
if "{STRING}" EQ "{STRTMP}"
    eval VALUE1 {COUNTER} OP - VALUE2 1 TO env:strlng{$$}
    ;echo "*N  String length : " NOLINE
    ;getenv strlng{$$}
else
    skip mlk02 BACK
endif
skip exit
lab exit
The result is retrievable with : getenv strlng<Shell_number>
Code:
getenv strlng1
Here is how it looks :

Last edited by malko; 05 November 2021 at 12:55.
malko is offline  
Old 26 October 2021, 11:45   #2
daxb
Registered User
 
Join Date: Oct 2009
Location: Germany
Posts: 3,303
I fear there isn't much interest in AmigaDOS 1.3 script stuff. 3.1 is already so limited that it doesn't make much fun if you want/need to write some more complex scripts. Best on Amiga is (guessing) ARexx but it also has its limits. Next level is Python but of course not on Amiga.

For me when I read AmigaDOS scripts I get eye cancer.
daxb is offline  
Old 26 October 2021, 17:09   #3
malko
Ex nihilo nihil
 
malko's Avatar
 
Join Date: Oct 2017
Location: CH
Posts: 4,856
It is sad for your eyes...
Maybe I will use the MagicWB colours set next time
malko is offline  
Old 02 November 2021, 22:43   #4
malko
Ex nihilo nihil
 
malko's Avatar
 
Join Date: Oct 2017
Location: CH
Posts: 4,856
Since the recursive call is the bottleneck here, I have revisited this 'strlng' command in order to try to improve the speed a bit.

After some rewrite I came to this new following code.
The improvement is quite noticeable as now it takes only 00:45 (45 seconds) to process a 17 characters string like "Scripting is fun!" where with the first version of the script it required 01:16.

NEW VERSION OF THE SCRIPT AVAILABLE BELOW. SEE POST #11

Code:
strlng_v2 :
.key CHAINE,QUIET/S
.bra {
.ket }
if NOT "{CHAINE}" EQ ""
	setenv >NIL: CHAINE{$$} "{CHAINE}"
	skip mlk02
endif
echo "  *e[33mIf the string contains space(s),*e[0m"
echo "  *e[33minput it with quotation marks.*e[0m    "

lab mlk01
echo "  What is your string ? " NOLINE
setenv >NIL: CHAINE{$$} ?
if "$CHAINE{$$}" EQ ""
	skip mlk01 BACK
endif
lab mlk02
;------------------------------------------------------
;Préparation pour l'édition ultérieure
;------------------------------------------------------
failat 11
setenv >NIL: STRlng{$$} 1
echo >t:rmcr{$$} "1CL//;w"
;------------------------------------------------------
;Ajouts des guillemets (car passage en paramètres)
;------------------------------------------------------
echo >env:CHAINE{$$}g "*"" NOLINE
getenv >>env:CHAINE{$$}g CHAINE{$$}
echo >>env:CHAINE{$$}g "*"" NOLINE
edit >NIL: FROM env:CHAINE{$$}g TO env:CHAINE{$$}gn WITH t:rmcr{$$}
run >NIL: delete env:CHAINE{$$}g
;------------------------------------------------------
;Création d'un 1er sous-script utilisant la valeur compteur
;------------------------------------------------------
echo >t:strlss1{$$} ".key COMPTEUR/A,PV*N.bra [*N.ket ]*Necho *>t:rmet{$$} *"pa l//" NOLINE
echo >>t:strlss1{$$} ";[COMPTEUR]*<;sa//;m1;d;w*" " NOLINE
echo >>t:strlss1{$$} "*Necho <env:CHAINE{$$}gn >env:CHAINE{$$}p NOLINE FIRST 1 LEN [COMPTEUR] ?*Nbreak {$$} C" NOLINE
protect t:strlss1{$$} +s
lab mlk03
;------------------------------------------------------
;Création d'un 2ème sous-script pour appeler le 1er en passant le compteur
;------------------------------------------------------
echo >t:strlss2{$$} "t:strlss1{$$} " NOLINE
getenv >>t:strlss2{$$} STRlng{$$}
protect >NIL: t:strlss2{$$} +s
run >NIL: t:strlss2{$$}
wait >NIL: 1 MIN
;------------------------------------------------------
;Nettoyage de l'extraction faite par le sous-script
;------------------------------------------------------
lab waitf
if NOT EXISTS env:CHAINE{$$}p
	skip waitf BACK
endif
edit >NIL: FROM env:CHAINE{$$}p TO env:CHAINE{$$}pn WITH t:rmet{$$}
;------------------------------------------------------
;Incrémentation du compteur
;------------------------------------------------------
if NOT "$CHAINE{$$}" EQ "$CHAINE{$$}pn"
	eval <env:STRlng{$$} >NIL: VALUE2 1 OP + TO env:STRlng{$$}.  ?
	setenv <env:STRlng{$$}. >NIL: STRlng{$$} ?
	skip mlk03 BACK
endif
;------------------------------------------------------
;Fin
;------------------------------------------------------
run >NIL: delete env:CHAINE{$$}#? env:STRlng{$$}. t:rmcr{$$} t:rmet{$$} t:strlss1{$$} t:strlss2{$$}  QUIET
if NOT "{QUIET}" EQ "QUIET"
	echo "  *e[32m$STRlng : " NOLINE
	getenv STRlng{$$}
	echo "*e[0m"
endif
quit
The result is available in the variable 'STRlng<shell_number>'

And here is how it looks :


Last edited by malko; 06 November 2021 at 00:36.
malko is offline  
Old 03 November 2021, 08:17   #5
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,323
It is fun to see how a programming language taken out of its normal scope can make a mountain out of a molehill...
meynaf is offline  
Old 03 November 2021, 10:39   #6
koobo
Registered User
 
koobo's Avatar
 
Join Date: Sep 2019
Location: Finland
Posts: 361
This is cool
I never looked much into scripting on the Amiga, it's interesting to see such complex things happening, especially on kick1.3.
koobo is offline  
Old 03 November 2021, 11:03   #7
malko
Ex nihilo nihil
 
malko's Avatar
 
Join Date: Oct 2017
Location: CH
Posts: 4,856
Thank you both

PS: Mountain is a bit strong, let's say instead an anthill
malko is offline  
Old 03 November 2021, 13:05   #8
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,323
Quote:
Originally Posted by malko View Post
PS: Mountain is a bit strong, let's say instead an anthill
That command would have been a lot easier to do in asm, actually
meynaf is offline  
Old 03 November 2021, 21:27   #9
malko
Ex nihilo nihil
 
malko's Avatar
 
Join Date: Oct 2017
Location: CH
Posts: 4,856
I believe you
Why not posting the corresponding asm code just below? (just for fun of course)
malko is offline  
Old 04 November 2021, 08:32   #10
meynaf
son of 68k
 
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,323
For the fun, yes, maybe, but it would still take significant time and efforts to have it run on 1.3, especially due i don't have such a setup.
And for 2.0 i would use my usual include files, which are not exactly public.
Also i don't know what exactly the program is supposed to do, i'm not shell expert enough to guess from the source.
meynaf is offline  
Old 06 November 2021, 00:35   #11
malko
Ex nihilo nihil
 
malko's Avatar
 
Join Date: Oct 2017
Location: CH
Posts: 4,856
We can say what we want, but it is true that we get better with practice .

While writing the 'ccase' command, I have realized that it was possible to revisit a bit the 'strlng' command for a new performance gain.

So, after a rewrite based on the code of my 'ccase' command, now this new 'strlng_v3' perform the count of the 17 characters long string "Scripting is fun!" in only 33 seconds !

01:16 (Initial version)
00:45 (v2 - 1.7x faster)
00:33 (v3 - 2.3x faster)

NEW VERSION OF THE SCRIPT AVAILABLE BELOW. SEE POST #13

Code:
strlng_v3 :
.key STRING/A,QUIET/S
.bra {
.ket }
;---------------------
;initialisation
;-
setenv cccptA{$$} 1
setenv cccptB{$$} 0
setenv ccstr0{$$} "{STRING}"
echo >env:ccstr9{$$} "" NOLINE
echo >env:ccstr9{$$}t "" NOLINE
echo >t:rmet{$$} "pa l//;<;sa//;p;d;w"
echo >t:rmeh{$$} "d;dfa/0A/;e/0A//;pa l//;2<;sa//;p;d;w"
lab mlk01
;---------------------
;début de boucle : preparation de l'extraction
;-
setenv <env:cccptA{$$} >NIL: echop{$$}t ?
echo >>env:echop{$$}t " LEN 1 *"{STRING}*"" NOLINE
echo >env:echop{$$} "FIRST " NOLINE
type >>env:echop{$$} env:echop{$$}t
;---------------------
;extraction par caractère, nettoyage et suppression du NUL/LF
;-
echo <env:echop{$$} >env:exstr1{$$}t ?
edit >NIL: FROM env:exstr1{$$}t TO env:exstr1{$$} WITH t:rmet{$$}
;---------------------
;contrôle si espace
;-
type >env:ehstr1{$$}t env:exstr1{$$}t opt h
edit >NIL: FROM env:ehstr1{$$}t TO env:ehstr1{$$} WITH t:rmeh{$$}
if "$ehstr1{$$}" EQ "20"
	eval "' " >NIL: TO env:slstr1{$$} lformat "%C"
else
	eval <env:exstr1{$$} >NIL: TO env:slstr1{$$} lformat "%C" ' ?
endif
lab mlk02b
;---------------------
;concaténation pour comparaison
;-
join env:ccstr9{$$}t env:slstr1{$$} AS env:ccstr9{$$}
copy env:ccstr9{$$} env:ccstr9{$$}t CLONE QUIET
lab mlk03
;---------------------
;la chaîne originale et recréée sont-elles identiques ?
;-
if "$ccstr9{$$}" NOT EQ "$ccstr0{$$}"
	;---------------------
	;incrémentation du compteur
	;-
	eval <env:cccptA{$$} >NIL: TO VALUE2 1 OP + TO env:cccptB{$$} ?
	setenv <env:cccptB{$$} >NIL: cccptA{$$} ?
	skip mlk01 BACK
endif
;---------------------
;fin
;-
copy env:cccptA{$$} env:STRlng{$$} CLONE QUIET
run >NIL: delete t:rm(et|eh){$$} env:cccpt(A|B){$$} env:(cc|ex|eh|sl)str(0|1|9){$$}#? env:echop{$$}#? QUIET
if "{QUIET}" NOT EQ "QUIET"
	echo "  *e[32m$STRlng{$$} : " NOLINE
	getenv STRlng{$$}
	echo "*e[0m"
endif
quit 0

Last edited by malko; 08 November 2021 at 01:27.
malko is offline  
Old 06 November 2021, 12:04   #12
daxb
Registered User
 
Join Date: Oct 2009
Location: Germany
Posts: 3,303
I know that you just doing it for the fun of 1.3 DOS scripting but 3.1 DOS is much equal. Hence the compare with the beauty of ARexx:
Code:
rx "say length('here you get the length of this string.')"
On my system (040/40) the operation takes 0,02 to 0,04 seconds with 17 or 200 chars.
daxb is offline  
Old 08 November 2021, 01:25   #13
malko
Ex nihilo nihil
 
malko's Avatar
 
Join Date: Oct 2017
Location: CH
Posts: 4,856
Thank you for this ARexx example daxb

To challenge this speed, I propose a final version that is, as your ARexx example, made without the need of any loop.

The command takes only two seconds regardless of the length of the string*. This little achievement is possible by using the list command to extract the size of the file that we create with the provided string.

*In fact, 'regardless' is not totally correct since the Shell command line cannot exceed the length of 254 characters (+ return). So, in this precise script case (with this name), the maximum lengths is (254 [shell maximum line length] - 10 [strlng_v4 ] = 244. To this, subtract 2 [if the string requires quotation marks] or/and subtract 6 [if you use the QUIET switch].
So, from 0 to 236-244


01:16 (Initial version)
00:45 (v2 - 1.7x faster)
00:33 (v3 - 2.3x faster)
00:02 (v4 - 38x faster)

Code:
strlng_v4 :
.key CHAINE/A,QUIET/S
.bra {
.ket }
;---------------------
;initialisation
;-
echo >t:rmlt{$$} "27#;5>;sa//;d;w"
lab mlk01
;---------------------
;sauvegarde de la chaîne de caractères dans un fichier
;-
echo >env:slstr0{$$} "{CHAINE}" NOLINE
;---------------------
;listing du fichier contenant la chaîne de caractères et nettoyage
;-
list >NIL: env:slstr0{$$} TO env:slcptA{$$}
edit >NIL: FROM env:slcptA{$$} TO env:slcptB{$$} WITH t:rmlt{$$}
if "$slcptB{$$}" EQ "empty"
	setenv STRlng{$$} 0
else
	eval <env:slcptB{$$} >NIL: TO env:slcptA{$$} ?
	setenv <env:slcptA{$$} >NIL: STRlng{$$} ?
endif
;---------------------
;affichage et fin
;-
run >NIL: delete t:rmlt{$$} env:slcpt(A|B){$$} env:slstr0{$$} QUIET
if "{QUIET}" NOT EQ "QUIET"
	echo "  *e[32m$STRlng{$$} : " NOLINE
	getenv STRlng{$$}
	echo "*e[0m"
endif
quit 0
malko is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
AmigaOS 1.3 ' ls ' command malko Coders. Scripting 10 19 November 2021 21:09
AmigaOS 1.3 'ccase' command malko Coders. Scripting 1 10 November 2021 23:24
AmigaOS 1.3 'wmn' command malko Coders. Scripting 0 01 November 2021 21:25
Is there a WB command at all that can... MethodGit request.Other 43 10 October 2010 09:06
What is the WB command that..... MethodGit request.Other 4 08 October 2010 04:21

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 15:23.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.19521 seconds with 13 queries