Jump to content











Photo
- - - - -

Writing to the Grub4dos' keyboard buffer possible?

grub4dos

  • Please log in to reply
110 replies to this topic

#51 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 112 posts
  •  
    Netherlands

Posted 29 June 2021 - 03:32 PM

I wish too Ctrl+RightArrow (or LeftArrow) would be possible on a Grub4Dos command-line, although in a script it is less useful than in text. For instance in Notepad++ '=%', '%' and '/' are counted as word's too (of course with good reasons). But on a very long line more 'speed' moving the cursor would be welcome 'as such'. Moving the cursor 'through' 510 chars on a Grub4Dos command-line is very, very slow with ArrowLeft/ ArrowRight. :(

 

Sadly calling Fn.5 x y  has no impact on the position of the cursor in a set /p command-line.

 

Even bad: if not x=0 the set /p command-line will start at the next line!

 

It looks like set /p ALWAYS 'populate' horizontal position 'zero' (I found Steve6375 opened an Grub4Dos-Issue about it).

 

Also call Fn.5 x y can not be combined with operator '&;' etcetera AFTER the call. Only with operator ';;' after calling Fn.5 0 y gives chosen y-line.

 

Please correct me if I am wrong. :ph34r:



#52 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 15923 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 30 June 2021 - 07:51 AM

Ah, well, if it's not possible (at the moment) it is not possible :(.

 

:duff:

Wonko



#53 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 112 posts
  •  
    Netherlands

Posted 30 June 2021 - 02:59 PM

Before we found the possibilities of INT16\AH=05h I started an investigation about writing my own command-line in a G4B-script, to overcome the limitations of the set /p command-line. Really complicated!

 

But your 'guardian angel'-delivery of working commands for Grubutil bios solved my main remaining problem with set /p.

 

During my editor-project I have to 'deal' with following limitations of the set /p command-line:

 

Problem in Project                                                   Priority    Workaround                                              

1. No highlighting/ colour of Message-part            LOW        NONE (by design)                 

2. No start after cursor-position '0'                           LOW        NONE (by design) - optical: spaces in Message-part

3. Maximum of 510 chars                                           HIGH       Split & copy larger lines to History Buffer; Join lines

4. No space possible on first position                       HIGH       Use of underscore as placeholder

5. No odd number of 'double quotes' possible        HIGH       Use of 'single quote'+underscore as placeholder

6. No operator+space possible on last position      HIGH       Use of operator+underscore as placeholder

7. Pre-fill from History Buffer                                     HIGH       Using Grubutil bios & INT16\AH=05h

8. No cursor control with Ctrl+ArrowLeft/ Right     MEDIUM  NONE (by design)

 

Although my workarounds are 'not so bad' and some accompanied with thrilling highlighted warnings (problems 4-6), the workarounds are not really 'user friendly' (if any). :unsure:



#54 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 112 posts
  •  
    Netherlands

Posted 10 July 2021 - 09:29 PM

Edit previous Post

 

1) My terminology about 'the set /p command-line' is probably not correct. Although according to 'Grub4dos Issue #48' internal function 'get_cmdline' is used (https://github.com/c...b4dos/issues/48), in fact it's more an 'insert-key-strokes-line for setting the set /p variable'. What's in a name? I'd like to have a correct one, although it will not be directly 'live-saving'.

2) In case of 'limitations of the set /p command-line' I meant use of the variable too. Problems 5 & 6 as described above are not a limitation of 'set /p' as such, but problems arise because I have to write the content of the 'set /p'-variable to memory in my editor-project.

 

New Post

 

I found a solution of 'Problem 5' and 'Problem 6' as described above, using the History Buffer.

So far I experimented with redirecting the content of the 'set /p'-variable to memory using echo %setpvar% > FILE or pause --wait=0 %setpvar% > FILE and even calling Fn.16.

Although pause is relatively the 'best' option with or without double-quotes before, after or around %setpvar% some lines are 'impossible' to redirect to memory. Apart from some, but only with workaround's described in my previous Post.

 

The solution is very easy: just read-out the last entry of the History Buffer and copy somewhere in memory after the 'insert-key-strokes-line for setting the set /p variable' is set with 'Enter'!

 

Following did the trick with my new sub-routine :histline if called with argument "1":

:histline #Get entries from History Buffer and copy to memory: max 510 chars; argument of the call is entry-number in History Buffer
setlocal && set * && set mdbase=%mdbase%
set /a histline=%~1 > nul
set /A address=0x3EA4C0 > nul
set /A entrylen=0x0 > nul
raw read %address% > nul &; set /A entrylen=%@retval% > nul
set /A mdbase=%mdbase%+0x4 > nul
:histloop #searches for entry-number defined by var 'histline'
if not %address%<=0x3EC3FF && endlocal && set success=N && goto :eof
set /A entrylen=0x0 > nul &; raw read %address% > nul &; set /A entrylen=%@retval% > nul
if %entrylen%==0x0 && endlocal && set success=N && goto :eof
set entrylen=%entrylen% &; set /a readlen=%@retval% > nul
if %readlen%>=6 && set /A entrylen=0x%entrylen:~-4,4%-0x2 > nul ! set /A entrylen=%entrylen%-0x2 > nul
set /a histline=%histline%-1 > nul &; if not %histline%==0 && set /A address=%address%+%entrylen%+0x2 > nul && goto :histloop
set /A buffskip=%address%+0x2 > nul
echo -n > (md)%mdbase%+4
if %entrylen%>=0x201 && set /A entrylen=0x201 > nul
#if %entrylen%>=0x7D0 && set /A entrylen=0x7D0 > nul
raw dd if=(md)0x0+0x1F63 of=(md)%mdbase%+4 bs=1 count=%entrylen% skip=%buffskip% seek=1 > nul
raw write --offset=0 (md)%mdbase%+4 \x22 > nul
cat --locate=\x00 --replace=\x22\x0A\x00 --number=1 (md)%mdbase%+4 > nul
endlocal && set success=Y && goto :eof

BTW in the last lines: 'seek=1' is needed because I use double-quotes around (so far), and the content of %setpvar% is terminated with line-feed '0A', like redirecting with pause %setpvar% > FILE (echo %setpvar% > FILE terminates with carriage-return+line-feed '0D0A').

Further: some lines can be combined too, if needed.

Also I don't know a better approach using read to find value of first two bytes on a memory address.

 

In the 'picture' below progress can be observed, earlier almost 'impossible' lines are easy-going now.

-------------------------------------------------------------------------------

----------------------------EDIT (fd0)/setp2mem.g4b----------------------------
0001 BAT 
0002 clear 
0003 echo abc 
0004 set /p "setpvar= STRING > " 
0005 set /p "setpvar= STRING > " ;; echo %setpvar% 
0006 " 
0007 "set /p "setpvar= STRING > " ;; echo %setpvar% 
0008 "set /p "setpvar= STRING > " ;; echo %setpvar%" 
0009 set /p "setpvar= STRING > " ;; echo %setpvar%" 
0010>set /p /a "choice= Choose number > " &; echo One double-quote " 
0011 
0012 :eof


even=Y linelen=0x3F line=set /p /a "choice= Choose number > "One double-quote "

00000000: 22 73 65 74  20 2F 70 20  2F 61 20 22  63 68 6F 69 ; "set /p /a "choi
00000010: 63 65 3D 20  43 68 6F 6F  73 65 20 60  75 61 62 65 ; ce= Choose numbe
00000020: 72 20 3E 20  22 20 26 33  20 65 63 68  6F 20 4F 6E ; r " &; echo On
00000030: 65 20 64 6F  75 62 6C 65  20 71 75 6F  74 65 20 22 ; e double-quote "
00000040: 22 0A 00 00  00 00 00 00  00 00 00 00  00 00 00 00 ; "...............
-------------------------------------------------------------------------------

BTW the setpvar on Line 0010 can't be even echoed normally (only with cat). The 'picture' is after entering the setpvar-content, and paused for debugging.


Edited by deomsh, 10 July 2021 - 09:32 PM.


#55 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 15923 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 11 July 2021 - 08:31 AM

Also I don't know a better approach using read to find value of first two bytes on a memory address.

 

I am not sure to understand (actually I am pretty sure to not understand) can you explain what the question (if any) is?

Better than what?

 

:duff:

Wonko



#56 steve6375

steve6375

    Platinum Member

  • Developer
  • 7453 posts
  • Location:UK
  • Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films,guitars, www.easy2boot.com
  •  
    United Kingdom

Posted 11 July 2021 - 10:41 AM

you can use calc to get a word value from memory

 

calc *%address% & 0xFFFF

echo %@retval%

 

or

debug 1

raw calc *%address% & 0xFFFF | set myword=


Edited by steve6375, 11 July 2021 - 10:48 AM.

  • deomsh likes this

#57 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 112 posts
  •  
    Netherlands

Posted 11 July 2021 - 01:13 PM

Thanks steve6375, this did the trick!

Wonko: sorry for my bad English. Maybe my sentence should have been: 'Also I don't know a better approach THAN using 'read' AND A TEXT BASED APPROACH to find value of first two bytes on a memory address'?

Using 'read' always returns 4 bytes in hex (of cause without leading zero's).

In case of an entry in the History Buffer, first two bytes (little endian style!) are giving the length of the entry, including those first two bytes and terminating '00. So minimum is 0x4. Written in memory: 04 00. If for instance 'WS' is inserted with 'set /p', the entry in the History Buffer is: 05 00 57 53 00.
With 'read' I get 0x53570005. That's why I used a text based approach to get two lowest bytes only.

steve6375' use of 'calc' is far more easier. And not unimportant: more economical. Because I'm running out of space: my editor-script is already about 1900 lines. Isn't it the maximum is 2000 lines?

Edited by deomsh, 11 July 2021 - 01:34 PM.


#58 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 15923 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 11 July 2021 - 02:06 PM

you can use calc to get a word value from memory

calc *%address% & 0xFFFF
echo %@retval%

or
debug 1
raw calc *%address% & 0xFFFF | set myword=


Yep :thumbsup: , but are those two, the first or the last two bytes? (First in memory, last in hex number or value)

More than that, in which order are they? (They might need to be inverted)

I.e.:
read 0x6125
Address 0x6125: Value 0x31c18e05

raw calc *0x6125 & 0x0000FFFF
36357 (HEX:0x8E05)

What is actually in memory should be 058EC131, there is the usual "issue" about Little Endian, so it depends if what is wanted at the end is a value or a hex dump, i.e.
cat --hex --length=4 --skip=0x125 (md)0x30+1
00000125: 05 E8 C1 31

 

@deomsh

No problem with your English, sometimes you have a clear concept in your head but somehow fail in expressing it in such a way that it cannot be misinterpreted, it happens to me lots of time in Italian as well (which I should know quite well), what is first and last depends on the way you look at it ;), Little or Big Endian is traditionally a potential issue.

A classic one is the way a Disk Signature is used in - say - the registry and how it is rendered/read by some tools (by the same good MS guys). 

:duff:
Wonko



#59 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 112 posts
  •  
    Netherlands

Posted 11 July 2021 - 09:54 PM

@Wonko

Difficult to express in (human) words. I OCR'd a screenshot to discuss things. I only added line-numbers.

Limbo x86 PC Emulator

grub> debug on 
grub> echo-n > (md)0x3000+1 
grub> cat --hex --length=16 (md)0x3000+1 
00000000: 00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00 ; ................
grub> write 0x600000 0x53570005
Address 0x600000: Value 0x53570005 
grub> cat --hex --length=16 (md)0x3000+1 
00000000: 05 00 57 53  00 00 00 00  00 00 00 00  00 00 00 00 ; .WS.............
grub> read 0x600000 &; set /A entrylen=%@retval%
Address 0x600000: Value 0x53570005
 1398210565 (HEX:0x53570005) 
grub> set entrylen=%entrylen% &; set /a readlen=%@retval%
 10 (HEX: 0xA) 
grub> if not %readlen%<=6 && set /A entrylen=0x%entrylen:~-4,4%
 5 (HEX:0x5) 
grub> calc *0x600000 & 0xff
 5 (HEX:0x5) 
grub> calc *0x600000 & 0xffff
 5 (HEX:0x5) 
grub> calc *0x600000 & 0xffffff
 5701637 (HEX:0x570005) 
grub> calc *0x600000 & 0xffffffff
 1398210565 (HEX:0x53570005) 
grub>_

On line 7 and 10 can be seen that if writing with write a hexadecimal representation of bytes directly to a memory address, the result is written in inversed, little-endian order. Using read gives next inversed order of four bytes back (lines 11-13), so equal to earlier input in hex.

Lines 14-17 are showing use of my textual-approach. Lines 18-25 are showing use of calc.

 

The first entry in History Buffer if keystrokes WS are given, looks like the hex-dump in line 10 (except the address of course). The header/index/prefix/counter (?) are the first two bytes, their order is litte-endian. So my need is to read-out the two lowest bytes, in little-endian the first two bytes, in hex the last two bytes.

The two ASCII-codes are written by Grub4Dos to the History Buffer in the same order as the key-strokes on the command-line (or on the set /p-input-line).

 

Maybe the text-based approach can be further simplified, because zero's give no output at all with read, and if the lowest byte (first byte in little-endian) is non-zero, at least a third, non-zero byte, will exist in the entry in the History Buffer.

 

If I am right, the easiest one-line text-based approach with read in this case will be (without  > nul):

 

set /A entrylen=0x0 && read 0x600000 &; set /A entrylen=%@retval% &; set /A entrylen=0x%entrylen:~-4,4%

 

 

One-line with calc (without  > nul):

 

set /A entrylen=0x0 && calc *0x600000 & 0xFFFF &; set /A entrylen=%@retval%

 

BTW For me it's very confusing, that, if an empty memory location is read-out with read, %@retval% returns 0 only OR if used on a new line, OR if used after the ;;-operator. Never after &;-operator or &&-operator.
 

Further about expressing my idea's in human language: you are fully right. Most of the time things are 'going bad' if I add sentences after my post is actually finished already (like this one) :rolleyes:


Edited by deomsh, 11 July 2021 - 09:55 PM.


#60 steve6375

steve6375

    Platinum Member

  • Developer
  • 7453 posts
  • Location:UK
  • Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films,guitars, www.easy2boot.com
  •  
    United Kingdom

Posted 11 July 2021 - 10:22 PM

I am not sure you understand what && || &;  |; and ;; mean?

 

&& means if the result of the previous command was true (1 or more - or more strictly not 0 or not false)

 

If you use a set command, the result returned by set is the length of the string

 

so  set /A entrylen=0x0    will set entrylen to  0x0  which has a length of 3 and so 3 will be returned = true

set /A entrylen=0   will also return 3  (0x0)  as will set /A entrylen=0x9

but set /A entrylen=17 will set the variable to 0x11 and so the command will return 4

 

also the && and || operations do not alter the environment until the whole line has executed, so 

set A=3
set A=4 && echo %A%

will echo 3  (not 4)  - and the && really makes no sense because no matter what you set A to, the number of characters will always be greater than 0!

 

However the ;&  ;| and ;; operators act after the environment has been changed (as if each command was on a new line)

 

so

set A=3
set A=4 ;; echo %A%

will echo 4 and is exactly the same as

set A=3
set A=4
echo %A%

So your code line can just be

raw calc *0x600000 & 0xFFFF > nul ;; set /A entrylen=%@retval% > nul

or use

debug 0
raw calc *0x600000 & 0xFFFF ;; set /A entrylen=%@retval% 

to avoid the characters on the screen

 

I can recommend a good book here   ;-)

 

or you can use the primer here (but translated from Chinese so the formatting/syntax/punctuation may be a bit wonky!)



#61 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 15923 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 12 July 2021 - 10:35 AM

Sorry, I still don't understand.

Let's say that in memory at that address you have (hex dump):
05 00 57 53
that corresponds to hex value 0x53570005

You want to get into a variable the value of (hex dump):
05 00
that corresponds to hex value 0x0005 or 0x5

Or do you want a sequence of 05 00?

If you want the value the

set /A myval=*0x6125 & 0x0000FFFF

seems to me perfect/easier. :dubbio:

If you want the sequence, it becomes tricky due to the elision of leading 00's, since you want a sequence of two bytes, and the value (in the "best" case) is 4 character long and (in the "worst") case is only 1 character long, but the the leading two characters are alway 0x you can "inject" 3 zeroes and "parse from the bottom.

Something like this might do:

set /A myval=*0x6125 & 0x0000FFFF
set mystr=000%myval:~2%
set myseq=%mystr:~-2,2% %mystr:~-4,2%

Actually you don't really-really need to inject three zeroes in a string, when you can add (say) 0x10000 to the value in the same set operation:
set /A myval=*0x6125 & 0x0000FFFF + 0x10000
set myseq=%myval:~-2,2% %myval:~-4,2%

still two lines, though, but this should work :unsure::

set /A myval=*0x6125 & 0x0000FFFF + 0x10000 ;;set myseq=%myval:~-2,2% %myval:~-4,2%

:duff:
Wonko



#62 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 112 posts
  •  
    Netherlands

Posted 12 July 2021 - 04:45 PM

@steve6375

I have grasped the idea of the meaning of && || &; |; and ;; in simple cases.

 

I am studying your site RMPrepUSB a lot. Tutorials 021a-e; 065 and 071 are offline available on my smartphone (thanks to browser Vivaldi). Two years ago I bought your e-book, it's worth every penny. I believe I mentioned your book earlier in this thread.

 

But because of my way of writing script lines 'things' are more complicated: I use many if-statements, also calling sub-routines and continue on the same line after returning from a call. In that case I tend to use more and more &; sometimes before, but especially after a call, to be sure all variables are refreshed. I 'do' what is working for me, but sometimes I do not understand the logic 'behind'.

 

BTW I use ;; as less as possible.

 

Maybe you can explain why variables are not refreshed in following script:

!BAT
#REFRESH.G4B - Test call's
debug 0
set call=Y
if %call%==Y && set called=Y && call :refresh1 && echo 1.2 goback=%goback%
echo 1.3 goback=%goback% && set goback=
if %call%==Y && set called=Y && call :refresh2 && echo 2.2 goback=%goback%
echo 2.3 goback=%goback% && set goback=
if %call%==Y && set called=Y && call :refresh3 && echo 3.3 goback=%goback%
echo 3.4 goback=%goback% && set goback=
goto :eof

:refresh1
echo 1.1 called=%called%
set goback=Y
goto :eof

:refresh2
setlocal && set * && set called=%called%
echo 2.1 called=%called%
set goback=Y
endlocal && set goback=%goback%
goto :eof

:refresh3
setlocal && set * && set called=%called%
echo 3.1 called=%called%
set goback=Y
endlocal && set goback=%goback%
echo 3.2 goback=%goback%
goto :eof

:eof

This is the output:

grub> refresh.g4b
1.1 called=Y
1.2 goback=
1.3 goback=Y
2.1 called=Y
2.2 goback=
2.3 goback=Y
3.1 called=Y
3.2 goback=Y
3.3 goback=
3.4 goback=Y
grub>_

With &; after the call's everything is fine, as can be expected.
 

Further:

With your solution with calc the ;;-operator is needed too to continue AFTER %@retval%. In my script-lines in this case no problem (see below), because there is no if-statement used before the ;;-operator.

%@retval% does not exist if first two bytes are empty (reading from left to right in little-endian). But in that case my idea to set /A entrylen=0x0 before makes no sense, so you are fully right.

 

@Wonko

I just need the hex-value, so if in memory is written in little-endian 05 00 57 53 I just need 0x5 (or 0x0005, but leading zero's are stripped of course).

 

set /A myval=*%address% & 0x0000FFFF is an excellent solution, also no need for new line or ;;-operator. Output is 0x0 if first two bytes in memory are empty.

Are the leading zero's in & 0x0000FFFF really needed? I found no difference in output without them (using only 0xFFFF).

 

Following four lines in the sub-routine :histline above, can now be 'compressed' to one line.

 

Before:

set /A entrylen=0x0 > nul &; raw read %address% > nul &; set /A entrylen=%@retval% > nul
if %entrylen%==0x0 && endlocal && set success=N && goto :eof
set entrylen=%entrylen% &; set /a readlen=%@retval% > nul
if %readlen%>=6 && set /A entrylen=0x%entrylen:~-4,4%-0x2 > nul ! set /A entrylen=%entrylen%-0x2 > nul

 

After:

set /A entrylen=*%address% & 0x0000FFFF > nul &; set /A entrylen=%entrylen%-0x2 > nul &; if %entrylen%<=0x0 && endlocal && set success=N && goto :eof

 

 

With calc:

calc *%address% & 0xFFFF > nul ;; set /A entrylen=%@retval%-0x2 > nul &; if %entrylen%<=0x0 && endlocal && set success=N && goto :eof



#63 steve6375

steve6375

    Platinum Member

  • Developer
  • 7453 posts
  • Location:UK
  • Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films,guitars, www.easy2boot.com
  •  
    United Kingdom

Posted 12 July 2021 - 05:01 PM

if %call%==Y && set called=Y && call :refresh1 && echo 1.2 goback=%goback%

 

The first thing the grub4dos parser does is to replace all %xxxx% parameters  (unless there is a ^ character inside the parameter)

 

so we get

 

if Y==Y && set called=Y && call :refresh1 && echo 1.2 goback=

That line is then executed

 

So you would need to write

if %call%==Y && set called=Y && call :refresh1 && call echo 1.2 goback=%^goback%

 

P.S. using call forces grub4dos to print the value of goback - without the call it would print '%goback%' (8 characters)!

 

but there is no need to use && because you are not testing anything - so just use ;;

if %call%==Y set called=Y ;; call :refresh1 ;; echo 1.2 goback=%goback%

 

same with the other lines


Edited by steve6375, 12 July 2021 - 05:52 PM.


#64 steve6375

steve6375

    Platinum Member

  • Developer
  • 7453 posts
  • Location:UK
  • Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films,guitars, www.easy2boot.com
  •  
    United Kingdom

Posted 12 July 2021 - 05:37 PM

You say '%@retval% does not exist if first two bytes'

but %@retval% always 'exists' - it is a number - it may be 0 or a negative or positive integer???

 

 

Wonkos solution of using set with  *memloc and & is better than calc, but I dont understand your line

 

set /A entrylen=*%address% & 0x0000FFFF > nul &; set /A entrylen=%entrylen%-0x2 > nul &; if %entrylen%<=0x0 && endlocal && set success=N && goto :eof

 

why use &;  when you are not testing the length of the variable entrylen which will be '0x0' at the shortest and so the result will always be 3 or more = true!

 

also you use  if %entrylen%<=0x0 && endlocal && set success=N && goto :eof

 

no need for &&  as you already use if

 

if (test) (command) 

 

using /A or /a is irrelevant when  using  if %xxx%==number  - grub4dos compares the numbers

so if %entrylen% is the string '0x0'  then all these will work

if %entrylen%==0

if %entrylen%==0x0

if "%entrylen%"=="0x0"     - string comparison

 

0x00000000000FFFF is the same as 0xFFFF, same as 000000001 is the same as 1.

 

so we get

 

set /A entrylen=*%address% & 0xFFFF - 2 > nul ;; if %entrylen%<=0 endlocal && set success=N && goto :eof

 

note that because you have used && here, it relies on the  endlocal and set command returned true (i.e. not 0) so it does work (as long as setlocal was used previously so endlocal will return true), but it is not a universal case because one of those commands could return 0 (depending on what it was) and then the rest of the commands would not execute. You need to be careful when using multiple && or &; on the same line as it depends on what command was executed just before.

 

grub4dos really needs a  if [TEST]  { command ; command ;; command }  type operator so you can have multiple commands based on an if result. I think the latest grub4efi understands braces to group multiple commands but not sure if the latest grub4dos version does?

 

hth



#65 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 15923 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 13 July 2021 - 07:19 AM

@Wonko

I just need the hex-value, so if in memory is written in little-endian 05 00 57 53 I just need 0x5 (or 0x0005, but leading zero's are stripped of course).

 

set /A myval=*%address% & 0x0000FFFF is an excellent solution, also no need for new line or ;;-operator. Output is 0x0 if first two bytes in memory are empty.

Are the leading zero's in & 0x0000FFFF really needed? I found no difference in output without them (using only 0xFFFF).

Good :).

 

Of course not, the leading 00's are not needed, it is a hex number/value, I tend to write them down anyway out of habit in cases like these only because they are an AND "mask", it is visually more evident (to me) that I am passing a value (that is 4 bytes long, or - more correctly  - of which only four bytes are relevant, as more are discarded by the previous implied 00's) through a "sieve" that lets through only the bytes where the FF's are. (in the general case of a 32 bit value).

 

Besides the fact that it is the same thing, if - like in this specific case - what one wants is only two bytes, the 0xFFFF works also "visually"    :thumbsup:

 

 

:duff:

Wonko



#66 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 112 posts
  •  
    Netherlands

Posted 13 July 2021 - 02:52 PM

 

Steve6375 said:

You say '%@retval% does not exist if first two bytes'

but %@retval% always 'exists' - it is a number - it may be 0 or a negative or positive integer???

 

@steve6375

I have tested my 'problem' again. You are right (of course), I was mistaken. Because of the logical operator (&& or || or &; or |;) I simply couldn't get it if the operator 'stops' executing the read-out-command.

 

So I will have to read-out %@retval% from a new line or after ;; (or give it a predefined value if the line is only executed if an preceding if-statement is true and I need a %@retval%-counter-value in lines afterwards if %@retval% isn't read-out (0 if using && or &; 1 if using || or |; ??).

 

But I believe you are against such a solution?

 

Solutions  calling a sub-routine or use if command goto :label to skip the lines related to the read-out %@retval% are possible of course, I sometimes use them. But will cost one label each time, and only 128 labels are supported - isn't it.

 

I have to deal with the constraints of Grub4Dos-scripting (I am aware off): 2000 lines, 60 (regular) variables, 128 labels and 1535/1536 chars on a line. With my current script I am reaching limits, and still not I all functionality I want to implement 'onboard'. I don't know a better solution than to making lines longer.

 

As a personal side-note: my eldest son, who is working as a professional programmer, sometimes laughs at me and say i have to learn C/C++ and write my scripts in that language and compile them for use on the Grub4Dos command-line. I still want to 'escape' this fate. :o

 

 

Steve6375 said:

why use &;  when you are not testing the length of the variable entrylen which will be '0x0' at the shortest and so the result will always be 3 or more = true!

 

What i like about Grub4dos-scripting it's so close  to ordinary thought (at least my ordinary way of thinking). I am just an 'ordinary Joe' and not a programmer. So to not to be misunderstood: I have not intention to lecture or criticize anyone, especially not steve6375, whose work I owe so much! Also I am very happy to be criticized, very helpful for me. Also give me ideas for new experiments to evaluate the way I am using Grub4dos-operators, and to find out 'what's in it for me'.

 

In my 'logical universe' I use &;  in the following way: 'If the preceding command is true, refresh variables and execute next command'. In case of setting some numerical value from %@retval%, &; is mandatory (as far I understand this subject).

 

Also I found that set (....) && ALWAYS returns %@retval%=1. Even with set a= or after set a= && set a=%a% &&

The case of set a= && set a=%a% &; echo %@retval% is a bit strange. Even if variable a doesn't exist, %@retval% still returns 1. But luckily it's consistent with my use of && and &; instead of the ;;-operator.

 

There is a practical advantage too: if working on big scripts like mine with length of lines up to more than 800 chars (800 in one single case), I just can use ONE # to comment out a whole line and try another-one. That's another reason why I am 'not so fond of' the ;;-operator. Although I will fully understand if any programmer will burst out laughing. :baby:

 

 

Steve6375 said:

no need for &&  as you already use if

 

if (test) (command)

 

I have tested this use of the if-command, but I 'can't live with it'. See following test:

grub> set a=A
grub> if %a%==A echo YES
YES
grub> set a=
grub> if %a%==A echo YES

Error 30: (http://grub4dos.chenall.net/e/30)
          invalid argument

grub> if %a%==A && echo YES
grub> _

I my editor-script I have a variable 'menu' to held the choice of a sub-menu from the main menu. Also I use variables 'read' 'edit' and 'write' to held the choices in their respective sub-menu's. Variables 'read' 'edit' and 'write' share many subroutines, if using 'if (test) (command)' I always have to test the existence of the variable to be evaluated first (only if not is 'safe').

 

With my &&-work-around this not needed (if believe you say in your book && is only mandatory in conjunction with !). I never ran into problem's with my &&-method.

 

 

Steve6375 said:

grub4dos really needs a  if [TEST]  { command ; command ;; command }  type operator so you can have multiple commands based on an if result. I think the latest grub4efi understands braces to group multiple commands but not sure if the latest grub4dos version does?

 

 

I looked in the latest version of Grub4Dos 0.4.6a 2021-06-02: can't find it.  :(

 

 

Steve6375 said:

if %call%==Y && set called=Y && call :refresh1 && echo 1.2 goback=%goback%

 

The first thing the grub4dos parser does is to replace all %xxxx% parameters  (unless there is a ^ character inside the parameter)

Thanks a lot :worship: :worship: :worship:

Now I understand why I ran into problems!

 

 

Steve6375 said:

but there is no need to use && because you are not testing anything - so just use ;;

if %call%==Y set called=Y ;; call :refresh1 ;; echo 1.2 goback=%goback%

 

If my preceding line set call=Y meant 'you are not testing anything' I understand.

 

I did some new tests, see below for the lines and screen-output:

!BAT
#REFRESH2.G4B Test call's
debug 0
clear
set call=zyx && set goback=
set /p "call= Test call's: Y=yes N=no > " && echo
if not %call%==Y if not %call%==N goto :eof
if %call%==Y set called=Y ;; call :refresh1 ;; echo 1.2 goback=%goback%
echo 1.3 goback=%goback%
goto :eof

:refresh1
echo 1.1 called=%called%
set goback=Y
goto :eof

:eof

Screen-output I
 Test call's: Y=yes N=no > Y
1.1 called=Y
1.2 goback=Y
1.3 goback=Y
grub> _

Screen-output II
 Test call's: Y=yes N=no > N
1.1 called=Y
1.2 goback=Y
1.3 goback=Y
grub> _

!BAT
#REFRESH3.G4B Test call's
debug 0
clear
set call=zyx && set goback=
set /p "call= Test call's: Y=yes N=no > " && echo
if not %call%==Y if not %call%==N goto :eof
if %call%==Y set called=Y && call :refresh1 &; echo 1.2 goback=%goback%
echo 1.3 goback=%goback%
goto :eof

:refresh1
echo 1.1 called=%called%
set goback=Y
goto :eof

:eof

Screen-output I
 Test call's: Y=yes N=no > Y
1.1 called=Y
1.2 goback=Y
1.3 goback=Y
grub> _

Screen-output II
 Test call's: Y=yes N=no > N
1.3 goback=
grub> _

Solution with call:

 

if %call%==Y && set called=Y && call :refresh1 && call echo 1.2 goback=%^goback%

 

give same result as REFRESH3.G4B.

 

Again: steve6375, thanks a lot, everything you said was very helpful. :)

 

BTW this is my first use of the quote-function while posting, don't see a possibility to add date/time 'automagically'



#67 steve6375

steve6375

    Platinum Member

  • Developer
  • 7453 posts
  • Location:UK
  • Interests:computers, programming (masm,vb6,C,vbs), photography,TV,films,guitars, www.easy2boot.com
  •  
    United Kingdom

Posted 13 July 2021 - 02:59 PM

Each .g4b file has the limits you mentioned, but you can call a second .g4b file or even more...

#68 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 15923 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 13 July 2021 - 06:08 PM

BTW this is my first use of the quote-function while posting, don't see a possibility to add date/time 'automagically'

Maybe because there isn't any.

Hint:
1) quote the whole post
2) delete from the quote the non-relevant part
3) rinse and repeat
 

Each .g4b file has the limits you mentioned, but you can call a second .g4b file or even more...

... or you could make a number of files consisting only of functions that can be used by several programs, we could call them "libraries" and "link" to them by calls, we could call them .lll, lousily (or loosely or lazily) linked libraries ;), then we could write scripts that essentially are made of a main() that consists of only calls and conditions ...

More seriously, there is a (DOS/NT) batch site that uses this approach (*everything* is written as a callable subroutine/function), though in that one the external library of functions is not explicit, it is more about "standard" subs that can be copy/pasted, JFYI:
https://www.dostips.com/
https://www.dostips....toFunctions.php
https://www.dostips....tCodeCmdLib.php
the general idea could be "ported" to grub4dos scripts, I believe.

:duff:
Wonko



#69 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 112 posts
  •  
    Netherlands

Posted 13 July 2021 - 11:04 PM

Good :).

 

Of course not, the leading 00's are not needed, it is a hex number/value, I tend to write them down anyway out of habit in cases like these only because they are an AND "mask", it is visually more evident (to me) that I am passing a value (that is 4 bytes long, or - more correctly  - of which only four bytes are relevant, as more are discarded by the previous implied 00's) through a "sieve" that lets through only the bytes where the FF's are. (in the general case of a 32 bit value).

 

Besides the fact that it is the same thing, if - like in this specific case - what one wants is only two bytes, the 0xFFFF works also "visually"    :thumbsup:

 

 

:duff:

Wonko

 

@Wonko

The use of a bitmask is very interesting, I believe it is a multiplication on bit-level, each bit individually multiplied with the corresponding bit of the bitmask. So, altough in hex stripped, the leading zero's will be still there in the 'background'. I expect 128-bits to be the maximum with Grub4Dos?

 

I only used & 0xFF before once, to modify the (only) Fn.4-call in my editor to find the position of a line. Because at that time I didn't find any example, I experimented to make following line (first && -operator is in fact not needed because in this case both variables always exist):

if %gotoline%==%linenum% && call Fn.4 &; set /a cursor=%@retval% > nul &; set /a cursor=%cursor%/256 > nul

Luckily my edit-lines never use position (0;0), so I didn't run into trouble.

 

For my ASCII-art project I needed an universal solution. With Google I found following on https://hybrid-analy...vironmentId=120 which uses & 0xFF. I believe it's related to RMPresUSB (so maybe from steve6375?)

call Fn.4 ;; set /A r=%@retval% > nul
set /a x=%r%>>8 > nul
set /a y=%r%&0xff > nul

After I understood x and y where transposed (not a problem as such, but for me mathematically confusing), Based on these lines I wrote an 'universal' sub-routine to find the cursor-coordinates, so no problem for me to use the ;;-operator:

:getxy #find cursor position. Empty 'echo -n' is needed for 'Fn.4' if no screen-output than the cursor exists
setlocal && set *
echo -n ;; call Fn.4 ;; set /A r=%@retval% > nul ;; set /a x=%r%&0xFF > nul ;; set /a y=%r%>>8 > nul
endlocal && set x=%x% && set y=%y%
goto :eof

Thanks to you and to steve6375 I have now a more clear concept of the &-operator.

 

BTW Today I saw there are (mathematically not confusing) examples in between on https://rmprepusb.co...ub4dos-internal (my off-line copy was from March, 17).

 

 

Each .g4b file has the limits you mentioned, but you can call a second .g4b file or even more...

 

@steve6375
I have considered this option, but didn't run any tests so far.

 

Speed is very important in my editor-script. Will it be possible to load other .g4b-files with insmod in memory and call them from the 'main' script? Are there any limits or constraints I should be aware of?
 

 

Maybe because there isn't any.

Hint:
1) quote the whole post
2) delete from the quote the non-relevant part
3) rinse and repeat
 

... or you could make a number of files consisting only of functions that can be used by several programs, we could call them "libraries" and "link" to them by calls, we could call them .lll, lousily (or loosely or lazily) linked libraries ;), then we could write scripts that essentially are made of a main() that consists of only calls and conditions ...

More seriously, there is a (DOS/NT) batch site that uses this approach (*everything* is written as a callable subroutine/function), though in that one the external library of functions is not explicit, it is more about "standard" subs that can be copy/pasted, JFYI:
https://www.dostips.com/
https://www.dostips....toFunctions.php
https://www.dostips....tCodeCmdLib.php
the general idea could be "ported" to grub4dos scripts, I believe.

:duff:
Wonko

 

@Wonko

Thanks a lot for the quote-instructions, it's doable.

 

I took a first look on the site you mentioned. About those universal libraries: if I consider them as standardized sub-routines, for instance like this one, can that be an example you are meaning, or is that too simple? I use it in more than one script:

:cleanmem #arguments basemd and memrange in 512-byte sectors; optional: only cleaned after skipmem 
setlocal && set *
set /A basemd=%~1 > nul
set /A memrange=%~2 > nul
set /A skipmem=%~3 > nul
set /A "basemd=%basemd% * 0x200 + %skipmem%" > nul
set /A "memrange=%memrange% * 0x200 - %skipmem%" > nul
call Fn.24 %basemd% 0x00 %memrange%
endlocal
goto :eof

But how to generate a consistent set of functions and arguments?

 

To minimize load-time a huge collection of .g4b-scripts can be easily copied from a folder to a Grub4Dos memdrive with my tool FATCOPY.G4B. So they can be used as external functions too.
 


Edited by deomsh, 13 July 2021 - 11:39 PM.


#70 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 112 posts
  •  
    Netherlands

Posted 14 July 2021 - 01:35 AM

Can't edit my Post anymore, don't know why, after two hours already??

Please only read the following.

@Wonko
The use of a bitmask is very interesting, I believe it is a multiplication on bit-level, each bit individually multiplied with the corresponding bit of the bitmask. So, altough in hex stripped, the leading zero's will be still there in the 'background'. I expect 128-bits to be the maximum with Grub4Dos?

I only used & 0xFF before once. Thanks to you and to steve6375 I have now a more clear concept of the &-operator.

@steve6375
I have considered this option, but didn't run any tests so far.

Speed is very important in my editor-script. Will it be possible to load other .g4b-files with insmod in memory and call them from the 'main' script? Are there any limits or constraints I should be aware of?

@Wonko
Thanks a lot for the quote-instructions, it's doable.

I took a first look on the site you mentioned. I will have to read far more closely before I will have any opinion on the subject.


Edited by deomsh, 14 July 2021 - 01:51 AM.


#71 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 15923 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 14 July 2021 - 08:27 AM

I took a first look on the site you mentioned. About those universal libraries: if I consider them as standardized sub-routines, for instance like this one, can that be an example you are meaning, or is that too simple? I use it in more than one script:

Sure, but like everyone else in this tiny grub4dos batch niche, you copy it and paste it (usually at the end) in your batch.

 

So you have that same function in many files.

 

This is good as you have re-usable code but self-standing batches (i.e. with no dependencies).

 

If you had thousands of batches and tens or hundreds of thousands of functions, you would do the same the good MS guys did, i.e. assemble all these functions into a set of libraries, and (dynamically) link to them, welcome to the world of .DLL's, and of dependencies.

 

The C that your son would like you to learn actually means "learn C for the basic logic of the program and the zillion functions/routines in the Windows API (i.e. in .dll's) that you'll need to call to actually write a program".

 

Right now (and afaik) the "grub4dos batch writers guild" :w00t: consists of a handful of members that produced essentially quick, simple scripts (additionally - at least mine - usually half-@§§ed)  to solve small, simple problems, there has never been any *need* to "offshore" functions to external files, let alone re-use them from several different batches, so there is not any previous experience, but it is doable.

 

You simply assemble all the generic functions in a file, assigning them a unique label (within the same library), then call the file with parameters and then (this is my suggestion but not necessarily a good one) use a same variable (analog to the special variable @retval) to get the result.

The "library file header" could be something *like*:
!BAT
call :%1

goto :eof

 

and then

:func_01

#do something
goto :eof

 

:func_02

#do something else
goto :eof

 

A poor example.

instead of:

set /a mysum=2+2

 

You could have:

mathfunc.g4b :sum 2 2

set /a mysum=%result%

 

and in the mathfunc.g4b something like:

 

!BAT
call :%1

goto :eof

and then

:sum

set /a result= %2 + %3

goto :eof

 

(not actually tested, nor really thought upon, just a generic idea)

 

 

:duff:

Wonko



#72 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 112 posts
  •  
    Netherlands

Posted 14 July 2021 - 02:38 PM

@Wonko

I am aware of DLL's and the Windows API. I am an 'adept' of the KernelEx-project, I even considered to learn the Windows API, but soon I found out the regular Windows API is already beyond my level, let alone Xeno86/ Jumper's extensions.

 

I tested your mathfunc.g4b, but as I expected, calling :%1 will not recuse %2 and %3 (I checked with debug mathfunc.g4b sum 2 2 too), but call :%1 %2 %3 is working (only in the called sub-routine %-arguments must set one number lower of course).

 

In my editor-project I found out goto :label unlimited recuse all %-arguments available (not sure if it's documented, if I found out by myself or if I just subcounsiously 'plagiarized' what I have been reading while 'Googling'). Looks more easy, but perchance there are other uses of call which do the same in this respect.

 

With extension to all four basic arithmetic operations, I have rewritten your mathfunc.g4b in the following way (I commented out other approaches tested during experimenting; echo's just for convenience):

!BAT #mathfunc.g4b by Wonko the Sane, modified by deomsh. Function: sum/substract/multiply/divide two values. Arguments: function, value1, value2
setlocal && set *
goto :%1
#call :%1 %2 %3
#set function=%1
#set function=:%function%
#set value1=%2
#set value2=%3
#call %function% %value1% %value2%
#call :%1
#goto :eof

:sum
#setlocal && set *
set /a result= %2 + %3 > nul
#set /a result= %1 + %2 > nul
endlocal && set result=%result%
echo %1: result=%result%
goto :eof

:substract
#setlocal && set *
set /a result= %2 - %3 > nul
endlocal && set result=%result%
echo %1: result=%result%
goto :eof

:multiply
#setlocal && set *
set /a result= %2 * %3 > nul
endlocal && set result=%result%
echo %1: result=%result%
goto :eof

:divide
#setlocal && set *
set /a result= %2 / %3 > nul
endlocal && set result=%result%
echo %1: result=%result%
goto :eof

#:eof

This is the 'print-screen'

grub> mathfunc sum 2 2
sum: result=4
grub> mathfunc substract 2 2
substract: result=0
grub> mathfunc multiply 2 2
multiply: result=4
grub> mathfunc divide 2 2
divide: result=1

BTW with only one variable result, use of setlocal && set * + endlocal && set result=%result% is 'overkill' and not needed, I just use it 'standard'.

 

 

I am not fully sure if such an extension of four functions in one script matches your idea of "generic functions in a file", nor even if I really have understood your approach. So feel free to criticise mine. :unsure:
 

 

 



#73 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 15923 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 15 July 2021 - 07:04 AM

Yep, but it's not my idea at all it is only a rough simplification/example of the general way of how the concept of libraries works.

 

Anyway (again generally):

goto :label means "go to" ;) label and continue from there, no parameters passed
call :label means go to label, pass parameters and return

 

using goto in this case is just fine, as long as you don't need to "post-process" the result after the execution of the function before returnign to the calling main batch, BUT in your example you repeat (without need) the 

echo %1: result=%result%

which could be written only once.

 

Has to be tested, but one could use

call %*

to pass on the whole set of parameters (no matter how many they are)

 

As well, most probably the setlocal and endlocal could be "global". :unsure:

 

i.e. (to be tested, if it works it is way more compact):

!BAT 
#mathfunc.g4b by Wonko the Sane, modified by deomsh re-modified by Wonko
#Function: sum/substract/multiply/divide two values. Arguments: function, value1, value2
setlocal && set *
call :%*
endlocal && set result=%result%
echo %1: result=%result%
goto :eof

:sum
set /a result= %2 + %3 > nul
goto :eof

:substract
set /a result= %2 - %3 > nul
goto :eof

:multiply
set /a result= %2 * %3 > nul
goto :eof

:divide
set /a result= %2 / %3 > nul
goto :eof

:duff:

Wonko



#74 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 112 posts
  •  
    Netherlands

Posted 15 July 2021 - 10:01 PM

Yep, but it's not my idea at all it is only a rough simplification/example of the general way of how the concept of libraries works.

In no way I meant to offense you, and your general approach. Just reported my expectations and experimental findings. But after two hours when I red my Post again, I realized it could be misunderstood. I tried to Edit my post, but too late already. Don't know why this forum don't let you to freely edit post's afterwards. Is it a restriction of the forum-software, or otherwise? Most of the time I post on MSFN, unlimited editing-possibilities (although the reason must be stated).

 

Anyway (again generally):

goto :label means "go to" ;) label and continue from there, no parameters passed
call :label means go to label, pass parameters and return

 

using goto in this case is just fine, as long as you don't need to "post-process" the result after the execution of the function before returnign to the calling main batch, BUT in your example you repeat (without need) the 

echo %1: result=%result%

which could be written only once.

 

In between I realized the parameters are still there after using goto :label, nothing else. In my project I have to post-process results too, but most of the time a 'go back' to a new label below the 'goto :label'-statement is working. Like this:

!BAT #mathfunc.g4b by Wonko the Sane, modified by deomsh(2). Function: sum two values. Arguments: function, value1,value2
setlocal && set *
goto :%1
:back
endlocal && set result=%result%
echo %1: result=%result%
goto :eof

:sum
set /a result= %2 + %3 > nul
goto :back

But sometimes I ran into big problems with a Grub4Dos error about 'logical structure is not good' or something like that. Very difficult to overcome, because debug refuses operation. Yesterday this happened too, while I tried a 'go to some label' at the end of the file to reduce number of endlocals/ echos to one. But today I could not reproduce this error.

 

Has to be tested, but one could use

call %*

to pass on the whole set of parameters (no matter how many they are)

 

As well, most probably the setlocal and endlocal could be "global". :unsure:

 

i.e. (to be tested, if it works it is way more compact):

!BAT 
#mathfunc.g4b by Wonko the Sane, modified by deomsh re-modified by Wonko
#Function: sum/substract/multiply/divide two values. Arguments: function, value1, value2
setlocal && set *
call :%*
endlocal && set result=%result%
echo %1: result=%result%
goto :eof

:sum
set /a result= %2 + %3 > nul
goto :eof

:substract
set /a result= %2 - %3 > nul
goto :eof

:multiply
set /a result= %2 * %3 > nul
goto :eof

:divide
set /a result= %2 / %3 > nul
goto :eof

:duff:

Wonko

Thanks a lot. I have tested your re-modification of MATHFUNC.G4B.

Because it didn't work at once, I was unsure if the colon in :%* would give equal result to :%1 %2 %3 but I had no earlier experience with using %*. The solution was simple: I just had to set %-numbers in set /a result=.... one lower. Still *somehow* strange the colon in :%* is 'set' only before %1

 

Now everything is working, and :%* seems to be a universal solution. :worship:

 

BTW while testing more combinations I maybe found a workaround for my call/ goto-problem. With call :label %* ALL available %-arguments are passed to the sub-routine too, and without shifting their number one down, once in the sub-routine . Which probably help me to overcome my goto-work-around (probably a bad one, and costs me one extra label too in case of a go-back).


Edited by deomsh, 15 July 2021 - 10:13 PM.


#75 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 15923 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 16 July 2021 - 07:36 AM

Don't worry, everything is cool, no offense whatever, it only seemed like you attributed me the idea while at the most I was clever :unsure: in exemplifying a known, established technique/approach.

 

The board is set for giving limited capabilities to posters will less than 50 posts (this is because of spammers editing previous posts to add links to crappy sites), you are near to reach that number of posts, from then on you will have no more time limits on editing previous posts.

 

The "shift" in the parameters is "normal".

 

When you call/execute an external file from a batch, like:

/mathfunc.g4b sum 2 3

%0=the name of the file called (/mathfunc.g4b in this case)

%1=sum

%2=2

%3=3

when the

call :%1 %2 %3

is executed, the parameters are re-enumerated as new and the first one is not a parameter of the call, but rather the label itself, i.e.:

%0=:sum
%1=2
%2=3

actually it is a "different set" of parameters that is "local" to the call, after the call is executed, if you return to the "main", the original set of parameters is restored.

Of course in the case of using goto (that does not allow parameters) the original set remains unchanged in all the batch.

 

The %* is ALL parameters excluded the %0 one.

 

In batch you have the shift command to manipulate parameter numbers/order, but the grub4dos implementation does not accept shift -1 if I recall correctly (not that it is usually needed).

 

quick example:



!BAT
echo %0 %1 %2 %3
echo %*
call :%*

echo after the call
echo %0 %1 %2 %3
goto :eof

:sum
echo here is mylabel
echo %0 %1 %2 %3
shift
echo %0 %1 %2 %3
shift
echo %0 %1 %2 %3

:duff:

Wonko







Also tagged with one or more of these keywords: grub4dos

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users