Author Topic: Different approach for Commandline arguments  (Read 19727 times)

0 Members and 2 Guests are viewing this topic.

JRS

  • Guest
Re: Different approach for Commandline arguments
« Reply #15 on: June 08, 2015, 02:15:33 PM »
Quote from: Arnold
but at least Scriptbasic has it's own way to retrieve the commandline, so there should be no problem.

Script BASIC gets its environment variables via the ENVIRON function.

Quote from: SB Docs
ENVIRON

This function returns the value of an environment variable. Environment variables are string values associated to names that are provided by the executing environment for the programs. The executing environment is usually the operating system, but it can also be the Web server in CGI programs that alters the environment variables provided by the surrounding operating system specifying extra values.

This function can be used to get the string of an environment variable in case the program knows the name of the variable or to list all the environment variables one by one.

If the environment variable name is known then the name as a string has to be passed to this function as argument. In this case the return value is the value of the environment variable.

If the program wants to list all the environment variables the argument to the function ENVIRON can be an integer number n. In this case the function returns a string containing the name and the value joined by a = sign of the n-th environment variable. The numbering starts with n=0.

If the argument value is integer and is out of the range of the possible environment variable ordinal numbers (negative or larger or equal to the number of the available environment variables) then the function returns undef.

If the argument to the function is undef then the function also returns the undef value.

Note that ScriptBasic provides an easy way for the embedding applications to redefine the underlying function that returns the environment variable. Thus an embedding application can "fool" a BASIC program providing its own environment variable. For example the Eszter SB Application Engine provides an alternative environment variable reading function and thus BASIC applications can read the environment using the function ENVIRON as if the program was running in a real CGI environment.

Code: Script BASIC
  1. i=0
  2. do
  3.   e$ = environ(i)
  4.   if IsDefined(e$) then
  5.     print e$
  6.     print
  7.   endif
  8.   i = i + 1
  9. loop while IsDefined(e$)
  10.  

Output

jrs@laptop:~/sb/sb22/test$ scriba env.sb
XDG_VTNR=7
XDG_SESSION_ID=c2
CLUTTER_IM_MODULE=xim
SELINUX_INIT=YES
XDG_GREETER_DATA_DIR=/var/lib/lightdm-data/jrs
SESSION=gnome-fallback-compiz
GPG_AGENT_INFO=/run/user/1000/keyring-18gpoe/gpg:0:1
TERM=xterm
SHELL=/bin/bash
XDG_MENU_PREFIX=gnome-flashback-
VTE_VERSION=3409
WINDOWID=62914571
OLDPWD=/home/jrs
UPSTART_SESSION=unix:abstract=/com/ubuntu/upstart-session/1000/2007
GNOME_KEYRING_CONTROL=/run/user/1000/keyring-18gpoe
PERL_MB_OPT=--install_base "/home/jrs/perl5"
GTK_MODULES=overlay-scrollbar:unity-gtk-module
USER=jrs
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:
XDG_SESSION_PATH=/org/freedesktop/DisplayManager/Session0
XDG_SEAT_PATH=/org/freedesktop/DisplayManager/Seat0
SSH_AUTH_SOCK=/run/user/1000/keyring-18gpoe/ssh
DEFAULTS_PATH=/usr/share/gconf/gnome-fallback-compiz.default.path
SESSION_MANAGER=local/laptop:@/tmp/.ICE-unix/2239,unix/laptop:/tmp/.ICE-unix/2239
XDG_CONFIG_DIRS=/etc/xdg/xdg-gnome-fallback-compiz:/usr/share/upstart/xdg:/etc/xdg
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
DESKTOP_SESSION=gnome-fallback-compiz
QT_IM_MODULE=ibus
QT_QPA_PLATFORMTHEME=appmenu-qt5
JOB=dbus
PWD=/home/jrs/sb/sb22/test
XMODIFIERS=@im=ibus
GNOME_KEYRING_PID=2002
LANG=en_US.UTF-8
GDM_LANG=en_US
MANDATORY_PATH=/usr/share/gconf/gnome-fallback-compiz.mandatory.path
UBUNTU_MENUPROXY=0
IM_CONFIG_PHASE=1
GDMSESSION=gnome-fallback-compiz
SESSIONTYPE=gnome-session
XDG_SEAT=seat0
HOME=/home/jrs
SHLVL=1
LANGUAGE=en_US
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
LOGNAME=jrs
XDG_DATA_DIRS=/usr/share/gnome-fallback-compiz:/usr/share/gnome:/usr/local/share/:/usr/share/
QT4_IM_MODULE=xim
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-xZpxtiegfc
LESSOPEN=| /usr/bin/lesspipe %s
INSTANCE=
TEXTDOMAIN=im-config
XDG_RUNTIME_DIR=/run/user/1000
DISPLAY=:0.0
XDG_CURRENT_DESKTOP=Unity
GTK_IM_MODULE=ibus
LESSCLOSE=/usr/bin/lesspipe %s %s
PERL_MM_OPT=INSTALL_BASE=/home/jrs/perl5
TEXTDOMAINDIR=/usr/share/locale/
COLORTERM=gnome-terminal
XAUTHORITY=/home/jrs/.Xauthority
_=/usr/bin/scriba
jrs@laptop:~/sb/sb22/test$


Windows XP

C:\sb22\test>scriba envwin.sb
ALLUSERSPROFILE=C:\Documents and Settings\All Users
APPDATA=C:\Documents and Settings\XP-User\Application Data
CLIENTNAME=Console
CommonProgramFiles=C:\Program Files\Common Files
COMPUTERNAME=VIRTUALBOX
ComSpec=C:\WINXP\system32\cmd.exe
FP_NO_HOST_CHECK=NO
HOMEDRIVE=C:
HOMEPATH=\Documents and Settings\XP-User
include=C:\Program Files\Microsoft Visual Studio\VC98\atl\include;C:\Program Files\Microsoft Visual Studio\VC98\mfc\include;C:\Progr
am Files\Microsoft Visual Studio\VC98\include
lib=C:\Program Files\Microsoft Visual Studio\VC98\mfc\lib;C:\Program Files\Microsoft Visual Studio\VC98\lib
LOGONSERVER=\\VIRTUALBOX
MSDevDir=C:\Program Files\Microsoft Visual Studio\Common\MSDev98
NUMBER_OF_PROCESSORS=1
OS=Windows_NT
Path=C:\Perl\site\bin;C:\Perl\bin;C:\Documents and Settings\All Users\Application Data\Oracle\Java\javapath;C:\Program Files\Windows
 Resource Kits\Tools\;C:\WINXP\system32;C:\WINXP;C:\WINXP\System32\Wbem;c:\scriptbasic\bin;C:\root\bin;C:\BASM\Bin;c:\Program Files\
Microsoft SQL Server\90\Tools\binn\;C:\TDM-GCC-32\bin;C:\Program Files\Microsoft Visual Studio\Common\Tools\WinNT;C:\Program Files\M
icrosoft Visual Studio\Common\MSDev98\Bin;C:\Program Files\Microsoft Visual Studio\Common\Tools;C:\Program Files\Microsoft Visual St
udio\VC98\bin;C:\Program Files\IDM Computer Solutions\UltraEdit\
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH
PROCESSOR_ARCHITECTURE=x86
PROCESSOR_IDENTIFIER=x86 Family 6 Model 37 Stepping 5, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=2505
ProgramFiles=C:\Program Files
PROMPT=$P$G
PYTHONPATH=C:\root\\bin
ROOTSYS=C:\root\
SESSIONNAME=Console
SystemDrive=C:
SystemRoot=C:\WINXP
TEMP=C:\DOCUME~1\XP-User\LOCALS~1\Temp
TMP=C:\DOCUME~1\XP-User\LOCALS~1\Temp
USERDOMAIN=VIRTUALBOX
USERNAME=XP-User
USERPROFILE=C:\Documents and Settings\XP-User
VS90COMNTOOLS=c:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools\
windir=C:\WINXP

C:\sb22\test>
« Last Edit: June 08, 2015, 03:20:18 PM by John »

Charles Pegge

  • Guest
Re: Different approach for Commandline arguments
« Reply #16 on: June 09, 2015, 12:19:12 AM »
Thanks everyone for all your input :)

My inclination is to put all the utilities required for handling command-lines into inc\ParseUtil.inc. A few extra functions are required, and then you will have all the tools needed for handling commands, config files, and mini-languages, for the price of about 8k of included source.

With functions like GetWord(source,index), the argc/argv construct may be redundant.

PS Oxygen strings are not char*, but downwards compatible with them. You must not specify a return string in a declaration where char* is returned. The length field expected by strings will not be present.

ParseUtil in its current form: (6k)
Code: OxygenBasic
  1.  
  2. sys    sttw    'word position
  3. sys    ascb    'word ascii code actual
  4. sys    ascw    'word ascii code presented
  5. sys    lenw    'word length
  6. sys    opw     'operator token
  7.  
  8.  
  9. function instrword(sys i,string s,k) as sys
  10. ===========================================
  11. sys  lk=len k,lb,rb
  12. byte b at strptr(s)
  13. if not k then return 0
  14. if i=0 then i=1
  15. do
  16.   i=instr(i,s,k)
  17.   if i=0 then
  18.     return 0
  19.   end if
  20.   lb=i-1
  21.   rb=i+lk
  22.   if b[rb]<33 then
  23.     if i=1 or b[lb]<33
  24.       return i
  25.     end if
  26.   end if
  27.   i+=lk
  28. end do
  29. end function
  30.  
  31.  
  32. function lookupindex(string s,k) as sys
  33. =======================================
  34. sys a
  35. a=instrword(1,s,k)
  36. if a then
  37.   return valat a+len(k)+strptr s
  38. end if
  39. end function
  40.  
  41.  
  42. function instrb(byte*bb,*bk) as sys
  43. ===================================
  44. sys b
  45. do
  46.   b=bb
  47.   select bk
  48.   case 0    : return 1
  49.   case b    : 'match chars
  50.  case else : return 0
  51.   end select
  52.   @bk++
  53.   @bb++
  54. end do
  55. end function
  56.  
  57.  
  58. function instrev(sys i,string s,k) as sys
  59. =========================================
  60. sys  a=asc k
  61. sys  lk=len k
  62. sys  ls=len s
  63. if i=0 then
  64.   i=ls
  65. elseif i>ls then
  66.   i=ls
  67. end if
  68. byte b at strptr s
  69. byte c at strptr k
  70. do
  71.   if i<1 then exit do
  72.   select b[i]
  73.   case a : if instrb(b[i],c) then exit do
  74.   end select
  75.   i--
  76. end do
  77. return i
  78. end function
  79.  
  80.  
  81. 'DEFAULT EQUATES
  82. ================
  83. %% SymbolTerm     40,41
  84. %% SymbolQuote    34,39,96
  85. %% SymbolComment  59
  86. %% SymbolEndLine  13,10,11,12
  87. %% SymbolEndState 41
  88.  
  89.  
  90. function skipspace(string s, sys*i)
  91. ===================================
  92. byte b at strptr s
  93. do
  94.   ascb=b[i]
  95.   ascw=ascb
  96.   select ascb
  97.   case 0              : exit do
  98.   case SymbolEndState : ascw=0 : exit do
  99.   case 33 to 255 :    : exit do
  100.   end select
  101.   i++
  102. end do
  103. end function
  104.  
  105.  
  106. function skiplspace(string s, sys*i)
  107. ====================================
  108. byte b at strptr s
  109. do
  110.   ascb=b[i]
  111.   ascw=ascb
  112.   select ascb
  113.   case 0              : exit do
  114.   case SymbolEndLine  : exit do
  115.   case SymbolEndState : ascw=0 : exit do
  116.   case 33 to 255      : exit do
  117.   end select
  118.   i++
  119. end do
  120. end function
  121.  
  122.  
  123. function endline(string s, sys*i)
  124. =================================
  125. byte b at strptr s
  126. do
  127.   select b[i]
  128.   case 0             : exit do
  129.   case SymbolEndLine : exit do
  130.   end select
  131.   i++
  132. end do
  133. end function
  134.  
  135.  
  136. function nextline(string s, sys*i)
  137. ==================================
  138. byte b at strptr s
  139. do
  140.   select b[i]
  141.   case 0        : exit do 'END OF STRING
  142.  case 10,11,12 : i++ : exit do
  143.   case 13       : i++
  144.     if b[i]=10 then i++
  145.     exit do
  146.   case else : i++
  147.   end select
  148. end do
  149. end function
  150.  
  151.  
  152. macro posword(s,i)
  153. ==================
  154. byte b at strptr s
  155. '
  156. rwordpos:
  157. '
  158. skipspace s,i
  159. sttw=i
  160. select ascb 'FIRST CHAR
  161. case SymbolTerm
  162.   i++ : jmp fwd nwordpos 'normally brackets    (  )
  163. case 0
  164.   jmp fwd nwordpos 'END
  165. case SymbolQuote
  166.   do
  167.     i++
  168.     select b[i]
  169.     case 0    : jmp fwd nwordpos
  170.     case ascw : i++ : jmp fwd nwordpos
  171.     end select
  172.   end do
  173.   jmp fwd nwordpos
  174. case SymbolComment
  175.   endline(s,i) : jmp rwordpos      ' ;   comment ;
  176. case 255
  177.   i++ : opw=b[i] : i++ : jmp fwd nwordpos 'EMBEDDED TOKEN
  178. end select
  179. do 'MOVE TO WORD BOUNDARY
  180.  select b[i]
  181.   case 0 to 32
  182.     exit do
  183.   case SymbolTerm
  184.     exit do
  185.   case SymbolQuote
  186.     exit do
  187.   case SymbolComment
  188.     exit do
  189.   case 255
  190.     exit do ' embedded token marker
  191.  end select
  192.   i++
  193. end do
  194. nwordpos:
  195. lenw=i-sttw
  196. end macro
  197.  
  198.  
  199. function stepword(string s,sys*i) as sys
  200. ========================================
  201. posword(s,i)
  202. end function
  203.  
  204.  
  205. function getword(string s, sys*i) as string
  206. ===========================================
  207. posword(s,i)
  208. return mid s,sttw,lenw
  209. end function
  210.  
  211.  
  212. function maygetword(string s, sys*i) as string
  213. ==============================================
  214. skiplspace s,i
  215. if ascb>32 then return mid s,sttw,lenw
  216. end function
  217.  
  218.  
  219. function isnumber() as sys
  220. ==========================
  221. select ascb
  222. case 47
  223. case 45 to 57 :return -1
  224. end select
  225. end function
  226.  
  227.  
  228. function isalpha() as sys
  229. =========================
  230. select ascb
  231. case 0x41 to 0x5a : return -1
  232. case 0x61 to 0x7a : return -1
  233. case "_" : return -1
  234. end select
  235. end function
  236.  
  237.  
  238.  
  239. function stepitem(string sr, sys*i)
  240. ===================================
  241. string wr
  242. sys bc
  243. stepword(sr,i)
  244. if ascw<>40 then return 'skip the word only
  245. 'otherwiwise skip block including any nested blocks
  246. bc++
  247. do 'STEP OVER NESTED BRACKETS
  248.  stepword(sr,i)
  249.   select ascw
  250.   case 0 :
  251.     if ascb = 41 then
  252.       if bc <= 0 then exit do
  253.       bc--
  254.     else
  255.       exit do
  256.     end if
  257.   case 40 : bc++
  258.   case 41 : bc--
  259.   end select
  260.   if bc=0 then exit do
  261. end do
  262. end function
  263.  
  264.  
  265. function getitem(string sr, sys*i) as string
  266. ============================================
  267. sys b,c
  268. skipspace(sr,i)
  269. b=i
  270. c=ascw
  271. stepitem(sr,i)
  272. sttw=b
  273. ascw=c
  274. return mid sr, b, i-b
  275. end function
  276.  
  277.  
  278. function unquote(string s) as string
  279. ====================================
  280. ascw=asc s
  281. select ascw
  282. case SymbolQuote :
  283.   if asc(s,-1)=ascw then
  284.     ascw=asc s,2
  285.     return mid s, 2, len(s)-2
  286.   end if
  287. end select
  288. return s
  289. end function
  290.  
  291.  
  292. function inner(string s) as string
  293. ==================================
  294. sys i=1, le
  295. 'EFFECTIVE LEFT TRIM
  296. skipspace(s,i)
  297. 'EFFECTIVE RIGHT TRIM
  298. le=len(s)
  299. byte b at le+strptr s
  300. le=le-i+1
  301. do
  302.   if le<=0 then exit do
  303.   @b--
  304.   if b>32 then exit do
  305.   le--
  306. end do
  307. le-=2
  308. i++
  309. if le>0 then return mid s,i,le
  310. end function
  311.  

Arnold

  • Guest
Re: Different approach for Commandline arguments
« Reply #17 on: June 09, 2015, 02:54:41 AM »
Hi Aurel,

I do not expect that OxygenBasic should be a clone of VB. Otherwise OxygenBasic would increase considerably in size and it would be not so fast. And if I understood it right, Oxygen is not intended to be a clone of any language but to use elements of Basic and C like languages, to support assembly and to be a companion tool for other languages in special cases. To achieve this purpose some compromises might be necessary. I myself am interested to learn and use the provided tools of Oxygen in a practical and logical way to get an intended result.

Out of curiosity I searched in Internet for some languages:

Freebasic: winbase.bi:
declare function GetCommandLine alias "GetCommandLineW" () as LPWSTR
declare function GetCommandLine alias "GetCommandLineA" () as LPSTR

Powerbasic: winbase.inc
DECLARE FUNCTION GetCommandLineA LIB "Kernel32.dll" ALIAS "GetCommandLineA" () AS DWORD

Rapidq: windows.inc
Declare Function GetCommandLine Lib "kernel32" Alias "GetCommandLineA" () As String

VBA (quote):
You also cannot directly use GetCommandLine in VBA declaration, something like
Declare Function GetCommandLine Lib "kernel32" Alias "GetCommandLineA" () As string
This simple code do not work, because GetCommandLine returns a pointer to string, which VBA cannot handle directly


I did not find more places with a declaration of GetCommandLine but what I found shows that at least a pointer to a null terminated string must be used. (Even with RapidQ and Visual Basic). I do not know in-depth the properties of the type string in OxygenBasic, but I think there is a reason for zstring, zstring2, asciiz, asciiz2 and char*. Maybe Charles will manage to adapt type string to be used for all purposes (which will certainly slow down the speed of compilation / execution), but it would not be fair to presume this as a "must be".

And I quote Charles:
Oxygen strings are not char*, but downwards compatible with them. You must not specify a return string in a declaration where char* is returned. The length field expected by strings will not be present.

For me it was a nice learning exercise to use:

   ! GetCommandLine alias "GetCommandLineA" lib "kernel32.dll" () as char*

   string cmdline = GetCommandLine
   int length=len(cmdline)

   print cmdline
   print length


Roland

Mike Lobanovsky

  • Guest
Re: Different approach for Commandline arguments
« Reply #18 on: June 09, 2015, 09:00:19 AM »
VB6's internal string format is exclusively COM-compatible Unicode. All direct communication with other COM servers in the system should be exercised via the respective COM interfaces declared in the form of standalone or embedded type libraries, in which case VB6 guarantees that it wouldn't perform any intrinsic transformations of byte-by-byte data of its textual string representations and would thus preserve compatibility with the other COM components in the system.

Declaring functions with Declare ... Lib ... Alias ... As String in 3rd party modules bypassing type libraries makes VB6 regard such functions as accepting and/or returning ASCIIZ and/or WCHAR strings only (a.k.a. LPSTR and LPWSTR in C notation, respectively) and triggers its built-in mechanism of associated string permutations. For example, in a call to such a 3rd party function, LenB(SomeVB6String) would pass the number of bytes counting one byte to a character rather than two bytes to a character like when it passes that number to native VB6 code. There are a hellofalot of other string function permutations VB6 does intrinsically and absolutely transparently when working with non-VB6 modules (DLLs), and it never fails.

So, Aurel, your impression that a VB6 String data type is equal to ASCIIZ/LPSTR/char* is nothing but your honest mistake and it only emphasizes how perfect VB6 in fact is. :)

As I understand it, Charles has succeeded in re-implementing much of similar approach in OxygenBasic and many permutations are made transparently to the user under the hood, but there are still some cases where 100% automatic conversion based on code flow analysis is not yet implemented. Hence the necessity for char*, rather than String, returns from 3rd party modules.

Aurel

  • Guest
Re: Different approach for Commandline arguments
« Reply #19 on: June 09, 2015, 09:36:11 AM »
Quote
So, Aurel, your impression that a VB6 String data type is equal to ASCIIZ/LPSTR/char* is nothing but your honest mistake and it only emphasizes how perfect VB6 in fact is. :)

Mike i understand very well and i know that is not the same
but from my experience with o2 i know that if you/me declare function in a VB style with given
type then in 90% of cases all things should work properly.
For example in same api declare with EBasic i can use type POINTER as result of this function
without problem.
Arnold use char in his subroutine because as local variable type string is terminated at
subroutine exit...right?

Mike Lobanovsky

  • Guest
Re: Different approach for Commandline arguments
« Reply #20 on: June 09, 2015, 10:00:34 AM »
but from my experience with o2 i know that if you/me declare function in a VB style with given type then in 90% of cases all things should work properly.

This means that Charles has already succeeded to provide us with automatic string type conversion in about 90% cases. Yet 10 more per cent left to go. :)

Quote
Arnold use char in his subroutine because as local variable type string is terminated at subroutine exit...right?

I think any local variable regardless of its type (including class instances) should ideally cease to exist automatically on proc exit. The only chance for its value to persist is to be copied to some intrinsic temp var used as the actual proc return value specific to a particular language engine implementation, in this form get propagated to the proc caller code, and finally assigned (copied) there again to some variable that still lives in that caller code.

In practice, however, such a perfect self-garbage-collecting mechanism is extremely difficult to design due to the abundance of possible choices of var types involved. But VB6 is a vivid example that it is possible. FBSL cannot automatically garbage collect only temporary class instance vars; they must be destroyed explicitly before the proc where they've been spawned in exits. Everything else is garbage collected automatically. Say, FBSL is 99% as perfect at it as VB6. O2 is 90%, that is, near, perfect at it now, but I have absolutely no doubt Charles will succeed 100%. :)

Charles Pegge

  • Guest
Re: Different approach for Commandline arguments
« Reply #21 on: June 09, 2015, 11:10:32 AM »
Oxygen can infer the correct format for passing most string and other args, even without a formal prototype declaration, but there is no way to infer what the return type might be. Therefore the return must be correctly declared, or cast when making the call. Fortunately char* returns are rare in Windows, and most procedures return data into a char* buffer provided by the caller.

In this case A string, bstring, or char buffer will be correctly handled, o2 automatically passes the char pointer of the string.


Mike Lobanovsky

  • Guest
Re: Different approach for Commandline arguments
« Reply #22 on: June 09, 2015, 11:58:11 AM »
Oxygen can infer the correct format for passing most string and other args, even without a formal prototype declaration ...

FBSL has done away with prototyping altogether. In fact, prototyping is letting the language decide for you what it thinks should be done with the var name you type. All prototyped functions in strongly typed languages look alike to the coder: foo name followed by opening parenthesis followed by a list of var names passed as foo bars followed by trailing closing parenthesis. Whatever the function effectively does with the args it accepts and how it treats them remains a mystery to the coder and a source of innumerous bugs when the poor soul just sits staring blankly at their screen not having the tiniest clue as to what's really failing so badly. That's because noone really looks into the header files they include in their projects so abundantly, and they recall that there's such a thing as the Win32 SDK Programmer's Reference (or MSDN, for that matter) only when their creations fail to start or corrupt their system memory to a BSOD.

The maximum FBSL would require from you if you want to call an external DLL function would be its name if you're planning to use this function alone. If a dozen or more functions are expected, it is possible to declare the DLL's name alone and FBSL would map its entire function name space into your process space automatically. You can even call a memory pointer without declaring it as executable code, optionally passing parameters. Stack adjustments on return are made automatically so that you don't give a damn if you're calling a CDECL or STDCALL DLL routine.

All the rest is however your own responsibility: if the function expects a pointer, then you are supposed to prepend the respective argument's var name with a PointerOf operator or its @ shorthand cast equivalent explicitly. Same for the $, %, %%, !, !! casts (String, Integer/Long/Boolean, Quad, Single and Double values, respectively).

Declarations/prototyping does not spare the coder the need to debug their creations where they would consult the manuals anyway just to see what this or that function really expects anyway. So why shouldn't they do it from the very beginning and ultimately avoid, rather than fix up, any and all bugs in the end?

Charles Pegge

  • Guest
Re: Different approach for Commandline arguments
« Reply #23 on: June 09, 2015, 01:26:46 PM »
Very interesting, Mike.

Can you handle aliases for mangled names, and A / W calls?

Mike Lobanovsky

  • Guest
Re: Different approach for Commandline arguments
« Reply #24 on: June 09, 2015, 05:31:34 PM »
Yes, of course, Charles.

Getting right through to a DLL's function name table via its PE header is a trivial problem solved in about four or five lines of C code (FBSL is written in MinGW/GCC). Resolving all possible associated relocations correctly given a function name would be a little trickier and bug prone, therefore I'm bluntly using GetProcAddress() on every function name in the list to get its entry point in the most fool-proof native MS way and then I'm simply demangling the names of possible underscores and at-endings and write them down into my own hash table of names and entry point addresses for FBSL's BASIC, DynC and DynAsm to use as if they were parts of language vocabulary proper. At this stage, all the functions found to be ending in capital A, i.e. ASCIIZ variants like SendMessageA, MessageBoxA, etc., are also aliased into the table without this trailing A, thus becoming SendMessage, MessageBox, etc., respectively. FBSL is a 32-bit ASCII-based language and it doesn't support Unicode directly, therefore its FooA() and Foo() calls are synonymic while SendMessageW, MessageBoxW and similar must be called explicitly. FBSL's BASIC provides buil-in AnsiToWide() and WideToAnsi() functions for conversion of strings between ASCII and Unicode.

Being primarily a GUI C-language program, FBSL has msvcrt.dll, kernel32.dll, user32.dll, and gdi32.dll already mapped into its process memory from the very start regardless of the script contents, therefore the function namespaces of these four DLLs are also mapped into FBSL's constituent language namespaces automatically at app start, providing the FBSL users with about 2,400 Win32 APIs as if they were parts of respective language vocabularies. I do not see any reason whatsoever to re-invent the wheel and bloat the language with commands and functions that are already provided by Win32 itself.

Mapping any other DLL into the process memory as needed is very simple: #DllImports OpenGL32, Glu32 et voila, the entire OpenGL (barring the extensions, of course) is at your feet, and its namespace, in your hands. :)

Arnold

  • Guest
Re: Different approach for Commandline arguments
« Reply #25 on: June 10, 2015, 09:58:28 AM »
This is the remaining part of my little project. Attached are two screenshots to show which information could be retrieved. Of course this is only one possibility to do it and there is no intention from my side to exert influence on any implementation. I do not even know if the code would work with Rtl64.inc. But of course it would be nice to have some tools for using the commandline.

Roland

Edit: code deleted

.
« Last Edit: June 10, 2015, 04:23:17 PM by Arnold »

Arnold

  • Guest
Re: Different approach for Commandline arguments
« Reply #26 on: June 10, 2015, 10:33:40 AM »
Hi Mike,

I just thought there was a message from you regarding pathnames / filenames with spaces.

I did not test this case. I did not even try to touch this situation. The problem is that gxo2.exe and co2.exe have a problem to run programs with spaces, so I used only paths / filenames without spaces. But you are right: this case should be considered too.

Roland

Arnold

  • Guest
Re: Different approach for Commandline arguments
« Reply #27 on: June 10, 2015, 11:45:47 AM »
Therefore I made a copy with name "Split Commandline.exe". This results to "Commandline.exe" as arg3. So something is missing in the splitCommandLine procedure which can be fixed. On the other hand gxo2.exe "Split Commandline.o2bas" does not work neither. It is a kind of borderline situation.

Roland

Aurel

  • Guest
Re: Different approach for Commandline arguments
« Reply #28 on: June 10, 2015, 12:59:03 PM »
In my simple editor RCode i use this two simple functions to get file name:
Code: [Select]
SUB GetFileName (src as string) as String

String fname,sign1,name
INT dotpos,bslashpos,nameLen
'print "ShowFName::TABCOUNT->:"+str(tabcount)
'C:\OxygenBasic\examples\GUI\SciEditor\WinControls.o2bas
src=Trim(src)
bslashpos = FieldCount(src,chr(92))
name = Mid(src,bslashpos+1,LEN(src))
dotpos = INSTR(name,".")
'print "DOTP:" + str(dotpos)
'nameLen = LEN(src)-(LEN(src)-dotpos)

name = Mid(name,1,dotpos-1)
'
'print "ShowName->:" + name

Return name
END SUB

Code: [Select]
SUB FieldCount(source As String,delimiter As String) as Int
Dim delpos,nexpos,count As Int
'delimiter=chr$(92)
count=1
delpos=1
nexpos=InStr(source,delimiter)
While nexpos
delpos=nexpos
nexpos=InStr(delpos+1,source,delimiter)
count++
Wend
RETURN delpos
END SUB 

Mike Lobanovsky

  • Guest
Re: Different approach for Commandline arguments
« Reply #29 on: June 10, 2015, 01:18:24 PM »
Hi Roland,

Thanks for making me aware.

I saw that your code skips spaces just after 'must start with value higher than space and thinking you did handle the space-delimited pathname case, I deleted my message but now I guess I was too quick in doing so.

It often happens that developers coming to MS Windows from *nix system overlook this peculiarity while the most common path where the users are supposed to keep their applications here appears to be space-delimited on default. So, handling tokens enclosed in double quotes that delimit such pathnames on a command line seems to be reasonable even in the simplest command line parsers.

It is also quite conventional here to use the %MAX_PATH equate (= 1024) when allocating buffers for any parts of a fully qualified path or file name, just to be on the safe side.