Author Topic: CommandLineToArgv  (Read 3914 times)

0 Members and 1 Guest are viewing this topic.

Spora

  • Guest
CommandLineToArgv
« on: March 25, 2016, 09:26:17 PM »
Do it is possibile to use CommandLineToArgv to parse CommandLine?
I'm not able:

Code: [Select]
short nArgs
long cmd
cmd=CommandLineToArgv(GetCommandLine, &nArgs)
MessageBox 0,cmd(2),str(nArgs),0

Charles Pegge

  • Guest
Re: CommandLineToArgv
« Reply #1 on: March 26, 2016, 01:25:21 AM »

Hi Spora,

Welcome to the forum!

This is one way to do it, using sysutil.inc It includes a full set of parsing functions, which are often needed in command-oriented programs.

Code: OxygenBasic
  1. includepath "$\inc\"
  2. include     "console.inc"
  3. include     "sysutil.inc"
  4.  
  5.   CreateArgv
  6.  
  7.  'test:
  8.  
  9.   for i=1 to argc
  10.     printl arga[i]
  11.   next
  12.   waitkey
  13.  

This is the macro CreateArgv in sysutil.inc:

Code: OxygenBasic
  1.   macro CreateArgv
  2.   ================
  3.   sys    argv[64], argc
  4.   string args= (char) GetCommandLine
  5.   string arga[64]
  6.   scope
  7.     indexbase 0
  8.     sys i=1
  9.     do
  10.       arga[argc]=unquote getword args,i
  11.       if ascb=0 then exit do
  12.       argv[argc]=strptr arga[argc]
  13.       argc++
  14.     end do
  15.   end scope
  16.   end macro
  17.  

[

Spora

  • Guest
Re: CommandLineToArgv
« Reply #2 on: March 26, 2016, 03:04:53 AM »
Ty.
Why pass array as argument not work?

Code: [Select]
includepath "$\inc\"
include     "console.inc"
include     "sysutil.inc"
 
CreateArgv

'test:

function main(int argc, sys argv[64])
for i=1 to argc
printl argv[i]
next
waitkey
END FUNCTION
main(argc, arga)

Arnold

  • Guest
Re: CommandLineToArgv
« Reply #3 on: March 26, 2016, 03:19:01 AM »
(deleted, obsolete)
« Last Edit: March 31, 2016, 05:06:24 AM by Arnold »

Arnold

  • Guest
Re: CommandLineToArgv
« Reply #4 on: March 26, 2016, 06:15:55 AM »
I am not sure if argc and argv are really necessary for main() in OxygenBasic. The strings are stored in arga. So my main procedure would be:

Code: OxygenBasic
  1. includepath "$\inc\"
  2. include     "console.inc"
  3. include     "sysutil.inc"
  4.  
  5.  
  6. sub main()
  7.    CreateArgv
  8.    
  9.    for i=1 to argc
  10.       printl arga[i]
  11.    next
  12.  
  13.    printl "Enter ... " : waitkey
  14. end sub
  15.  
  16. main()
  17.  

Roland

Charles Pegge

  • Guest
Re: CommandLineToArgv
« Reply #5 on: March 28, 2016, 11:04:36 PM »
If your preference is to use a C-style main:

Code: OxygenBasic
  1.  
  2. include     "console.inc"
  3. include     "sysutil.inc"
  4.  
  5. CreateArgv
  6.  
  7. function main cdecl (int argc,char**argv) as int
  8. ================================================
  9.   for i=1 to argc
  10.     printl argv[i]
  11.   next
  12.   waitkey
  13. end function
  14.  
  15. main argc, byval @argv
  16.  
  17.  

Arnold

  • Guest
Re: CommandLineToArgv
« Reply #6 on: March 30, 2016, 04:50:27 AM »
Hi Charles,

I tried your function main (I had to include: includepath "$/inc/") but I do not get the expected results. Did I miss something or do you already use a work in progress not yet published?

My output is:

C:\OxygenBasic\gxo2.exe
:\OxygenBasic\gxo2.exe

If I change argv to arga I would get the expected result. But maybe argv must be treated a little bit different?

Roland

Code: OxygenBasic
  1. includepath "$/inc/"
  2. #include "console.inc"
  3. #include "sysutil.inc"
  4.  
  5. CreateArgv
  6.  
  7. function main cdecl (int argc,char**argv) as int
  8. ================================================
  9.   for i=1 to argc
  10.     printl argv[i]
  11.   next
  12.   printl ""
  13.   for i=1 to argc
  14.     printl arga[i]
  15.   next
  16.   waitkey
  17. end function
  18.  
  19. main argc, byval @argv
  20.  

Charles Pegge

  • Guest
Re: CommandLineToArgv
« Reply #7 on: March 31, 2016, 01:02:01 AM »
Hi Roland,
Sorry. My error!:

The problem is in the CreateArgv macro in sysutil.inc:

  macro CreateArgv
  ================
  sys    argv[64], argc
  string args = CommandLineArgs ' not GetCommandLine
  string arga[64]
  scope
    indexbase 0
    sys i=1
    do
      arga[argc]=unquote getword args,i
      if ascb=0 then exit do
      argv[argc]=strptr arga[argc]
      argc++
    end do
  end scope
  end macro

Arnold

  • Guest
Re: CommandLineToArgv
« Reply #8 on: April 01, 2016, 12:57:04 AM »
Hi Charles,

I had to interrupt my tests yesterday therefore my response is a bit delayed.

There is still a problem with using argv to get the arguments in:
function main cdecl (int argc,char**argv) as int
There is no problem to get the arguments with arga though. Is char**argv the same as string *argv ? Somehow this construct looks like magic to me.

I have tried to arrange the possible variations to retrieve the arguments in OxygenBasic. Perhaps there is something additional to be considered for a C-style main function? To get the arguments outside of main or in main without parameters I applied the code of function f which is commented out in sysutil.inc. Using arga should work in any case.

Roland

Code: OxygenBasic
  1. $filename "GetCommandArgs.exe"
  2. '#include "$/inc/RTL32.inc"
  3.  
  4. includepath "$/inc/"
  5. #include "console.inc"
  6. #include "sysutil.inc"
  7.  
  8. CreateArgv
  9.  
  10. print"Get Arguments without main function"
  11. string cmd=(char) GetCommandLine
  12. printl "Commandline complete: " : printl cmd
  13.  
  14. printl ""
  15. printl "Number of Arguments: " argc
  16. for i=1 to argc
  17.   printl "Arga[" i "]: " arga[i]
  18. next
  19. 'argv
  20. sys i
  21. for i=1 to argc
  22.   char c at argv[i]
  23.   printl "Argv[" i "]: " c
  24. next
  25. printl ""
  26.  
  27.  
  28.  
  29. function main cdecl (int argc,char**argv) as int
  30. ================================================
  31.   printl "Get Arguments in: function main cdecl (int argc,char**argv) as int"
  32.   for i=1 to argc
  33.     printl "Argv[" i "]: " argv[i]  
  34.   next
  35.   for i=1 to argc
  36.     printl "Arga[" i "]: " arga[i]
  37.   next
  38.   printl ""
  39. end function
  40. main argc, byval @argv
  41.  
  42.  
  43. function main()
  44.   printl "Get Arguments in: function main() without arguments"
  45.   for i=1 to argc
  46.     printl "Arga[" i "]: " arga[i]
  47.   next
  48.   'argv
  49.  sys i
  50.   for i=1 to argc
  51.     char c at argv[i]
  52.     printl "Argv[" i "]: " c
  53.   next
  54. end function
  55. main
  56.  
  57. printl cr "Enter ..." : waitkey
  58.  

.

Charles Pegge

  • Guest
Re: CommandLineToArgv
« Reply #9 on: April 02, 2016, 01:21:17 AM »
Hi Roland,

Thanks for testing. I think we better give up on Char** for the moment.

I quite like this one, since it is unambiguous:

Code: OxygenBasic
  1. CreateArgv
  2.  
  3. typedef char *cstring
  4.  
  5. function main cdecl (int argc,cstring * argv) as int
  6. ====================================================
  7.   printl argc
  8.   for i=1 to argc
  9.     printl argv[i]
  10.   next
  11. end function
  12.  
  13.   main argc, byval @argv
  14.   waitkey
  15.  

The prototype can be further clarified by using an array indication instead argv[]:

Code: OxygenBasic
  1. CreateArgv
  2.  
  3. typedef char *cstring
  4.  
  5. function main cdecl (int argc,cstring argv[]) as int
  6. ====================================================
  7.   printl argc
  8.   for i=1 to argc
  9.     printl argv[i]
  10.   next
  11. end function
  12.  
  13.   main argc, byval @argv
  14.   waitkey
  15.  

Charles Pegge

  • Guest
Re: CommandLineToArgv
« Reply #10 on: April 02, 2016, 01:44:12 AM »
PS:

It you want i/o to appear in the main console window:

% TryAttachConsole

Code: OxygenBasic
  1. % TryAttachConsole
  2. include     "console.inc"
  3.  

Arnold

  • Guest
Re: CommandLineToArgv
« Reply #11 on: April 02, 2016, 04:38:14 AM »
Hi Charles,

after applying typedef char *cstring and using the modified main functions everything works fine.

Btw the derivation:

   char**argv
-->
   typedef char *cstring

   cstring * argv
   cstring argv[]

looks very conclusive and makes much sense. Would this approach be possible in some way for other types like int, doubles too? I have not yet tried this (pointers are my weak point anyway - in every programming language).

Quote
% TryAttachConsole

This will be one of my favorite keywords.

Roland

Charles Pegge

  • Guest
Re: CommandLineToArgv
« Reply #12 on: April 03, 2016, 12:26:25 PM »
Yes, [] can be used with any type, within a prototype, to indicate that a reference (base address) is being passed.

Thus
(double d[])
is the same as
(double * d)

but beware strings:

(string s[])  is an array of strings
whereas
(string *s) is one string passed by reference


« Last Edit: April 03, 2016, 10:10:11 PM by Charles Pegge »