26 October 2021, 00:27 | #1 |
Ex nihilo nihil
Join Date: Oct 2017
Location: CH
Posts: 5,089
|
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 Code:
getenv strlng1 Last edited by malko; 05 November 2021 at 12:55. |
26 October 2021, 11:45 | #2 |
Registered User
Join Date: Oct 2009
Location: Germany
Posts: 3,315
|
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. |
26 October 2021, 17:09 | #3 |
Ex nihilo nihil
Join Date: Oct 2017
Location: CH
Posts: 5,089
|
It is sad for your eyes...
Maybe I will use the MagicWB colours set next time |
02 November 2021, 22:43 | #4 |
Ex nihilo nihil
Join Date: Oct 2017
Location: CH
Posts: 5,089
|
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 And here is how it looks : Last edited by malko; 06 November 2021 at 00:36. |
03 November 2021, 08:17 | #5 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,366
|
It is fun to see how a programming language taken out of its normal scope can make a mountain out of a molehill...
|
03 November 2021, 10:39 | #6 |
Registered User
Join Date: Sep 2019
Location: Finland
Posts: 377
|
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. |
03 November 2021, 11:03 | #7 |
Ex nihilo nihil
Join Date: Oct 2017
Location: CH
Posts: 5,089
|
Thank you both
PS: Mountain is a bit strong, let's say instead an anthill |
03 November 2021, 13:05 | #8 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,366
|
|
03 November 2021, 21:27 | #9 |
Ex nihilo nihil
Join Date: Oct 2017
Location: CH
Posts: 5,089
|
I believe you
Why not posting the corresponding asm code just below? (just for fun of course) |
04 November 2021, 08:32 | #10 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,366
|
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. |
06 November 2021, 00:35 | #11 |
Ex nihilo nihil
Join Date: Oct 2017
Location: CH
Posts: 5,089
|
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. |
06 November 2021, 12:04 | #12 |
Registered User
Join Date: Oct 2009
Location: Germany
Posts: 3,315
|
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.')" |
08 November 2021, 01:25 | #13 |
Ex nihilo nihil
Join Date: Oct 2017
Location: CH
Posts: 5,089
|
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 |
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 |
|
|