+mizapf Posted October 5, 2022 Share Posted October 5, 2022 While I'm working on some test programs, I thought this tool could be helpful for others, so I'll publish it here. It is an extension of a 10-year-old work contained in my XMODEM tool, and it serves to parse the command line arguments when you run a program in MDOS. So this allows you to process the arguments in a line like testprog /n1000 /sMichael /i-10 hello It is also contained in the attached image. The license is the 2-clause BSD license, which basically says you should mention me as the author when you use it in your own distributed software. ***************************************************************** * * Command line parser for MDOS * * Boolean: /x is present, or not * Integer: /x<ws>*[<sign>]<value> delivers the signed value * String: /x<ws>*<string> delivers the null-terminated string * Hex: /x<ws>*<hexstring> delivers the value of the hexadecimally * interpreted last four characters of the hexstring * Direct: <ws>*<string> delivers the null-terminated string * (Argument without /x) * * No escaping or quoting; the arguments must not contain whitespace, * slashes, or NUL * * <ws>* = 0 or more whitespaces (space or tab) * * Example: * * LI R1,LINE Buffer where the argument string is copied to * BLWP @CLILIN * JEQ ARGSF * LI R1,NOARG Error message, "missing arguments" * JMP ERR * * ARGSF MOV R1,R0 LINE address now in R0 * LI R1,'s ' Line contains a /s1000 (or /s 1000) * LI R2,INT Integer * BLWP @CLIPRS * JEQ $+6 Yes, R3=1000, skip next line * LI R3,42 If not set, use 42 as a default * * Version 1.0 * * Copyright 2022, Michael Zapf * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ***************************************************************** DEF CLIPRS,CLILIN BOOL EQU 1 INT EQU 2 STRING EQU 3 HEX EQU 4 DIRECT EQU 0 WS BSS 32 SLASH BYTE '/' SPACE BYTE ' ' H2000 DATA >2000 TAB BYTE >07 H2B BYTE >2B H2D BYTE >2D H30 BYTE >30 H37 BYTE >37 H39 BYTE >39 H41 BYTE >41 H46 BYTE >46 TEN DATA 10 * Get arguments from CLI * Caller: * LI R1,BUFFER * BLWP @CLILIN * JEQ GOTIT * Buffer will be null-terminated CLWS BSS 32 CLILIN DATA CLWS,$+2 MOV @>0128,R0 JNE ST1 SZC @H2000,R15 RTWP ST1 CLR R2 MOV @2(R13),R3 MOV *R0+,R1 LI R5,6 MOVB *R0+,R2 DEC R5 SRL R2,8 GL1 MOVB *R0+,*R3+ DEC R2 JEQ GOTALL DEC R5 JNE GL1 MOV R1,R0 JEQ GOTALL MOV *R0+,R1 LI R5,6 JMP GL1 GOTALL CLR R1 MOVB R1,*R3 SOC @H2000,R15 RTWP * Originally, the parser was planned to accept an argument group (arggroup) * in this way: /n /m /i = /nmi * Also, the value of a valued parameter should be appended directly * like this: /c 1000 = /c1000 * This may be ambiguous, however, when n requires a value and m and i * are boolean switches: /nmichael * The parser cannot tell whether "i" is the flag or part of the value of n * unless we inform it that n is a valued parameter * Available data types FUNC DATA GBOOL,GINT,GSTR,GHEX CLIPRS DATA WS,$+2 MOV *R13,R0 MOV @2(R13),R1 MOV @4(R13),R2 CLR R5 Mode: /... !=0 , else 0 CI R2,DIRECT JNE GLOOP different parsing for direct B @GFD GLOOP MOVB *R0+,R4 JNE GLP0 SZC @H2000,R15 End reached, not found RTWP GLP0 CB R4,@SLASH JNE GLP1 SETO R5 Set slash mode on JMP GLOOP GLP1 CB R4,R1 JEQ FOUND CI R1,>6000 JH GLP3 GLP2 CLR R5 Reset slash mode JMP GLOOP GLP3 AI R4,>2000 CB R4,R1 JEQ FOUND JMP GLP2 FOUND CI R2,HEX JLE F1 SZC @H2000,R15 RTWP F1 DEC R2 SLA R2,1 MOV @FUNC(R2),R3 B *R3 * Check for whitespace * Argument in R10 HB * Returns EQ WSPACE CB R10,@SPACE JEQ WEND CB R10,@TAB WEND RT * -------------------------- * Check by data type * -------------------------- * ----- Boolean ------ * When it's found, it is set GBOOL SOC @H2000,R15 Then we have no value; set EQ RTWP * ----- Integer ------- * Added +/- * INT: skip ws, parse until next ws GINT CLR R6 Flag: !=0 <=> in number CLR R7 Sign present (0=no, -1=yes) CLR R8 Value (also R9) CLR R1 Sign (0=+, -1=-) GI1 MOVB *R0+,R4 JEQ GIEND Reached end of string MOVB R4,R10 BL @WSPACE JNE GI2 * ws is legal if we have a number, or if we neither have a number nor a sign MOV R6,R6 Do we have a number? JNE GI5 Yes, we are done MOV R7,R7 No number, but a sign? JEQ GI1 No, then continue JMP GERR Yes, then this is an error GI2 CB R4,@H2B Plus JEQ GI3 CB R4,@H2D Minus JNE GI4 SETO R1 Set minus flag GI3 MOV R7,R7 Do we have a sign already? JNE GERR Yes, then this is an error SETO R7 Now we have a sign JMP GI1 GI4 CB R4,@H30 JL GERR invalid character CB R4,@H39 JH GERR invalid character SETO R6 Valid digit SB @H30,R4 SRL R4,8 MPY @TEN,R8 R8 is our current number A R4,R9 R8/9 = R8 * 10 + R4 MOV R9,R8 Value in R8 JMP GI1 GIEND MOV R6,R6 Reached end; do we have a number? JEQ GERR no, so that is an error GI5 MOV R1,R1 Check sign JEQ GI6 NEG R8 GI6 MOV R8,@6(R13) Number in R8 goes to caller's R3 SOC @H2000,R15 was OK RTWP GERR SZC @H2000,R15 RTWP * --- String ----------------- * Skip whitespace before; * ends before first whitespace behind GSTR MOV @6(R13),R5 CLR R6 GS1 MOVB *R0+,R4 JEQ GS3 MOVB R4,R10 BL @WSPACE JNE GS2 MOV R6,R6 JEQ GS1 JMP GS4 GS2 SETO R6 MOVB R4,*R5+ JMP GS1 GS3 MOV R6,R6 JEQ GS5 GS4 CLR R0 MOVB R0,*R5+ Null termination SOC @H2000,R15 RTWP GS5 SZC @H2000,R15 RTWP * ------ Hex value ------- * If there are more than four digits, the leftmost digits are ignored * 12ABC5 = ABC5 GHEX CLR R6 Flag: !=0 <=> in number CLR R8 GH1 MOVB *R0+,R4 JEQ GH2 Reached end of string MOVB R4,R10 BL @WSPACE JEQ GH3 BL @HEXDIG MOVB R10,R10 JLT GERR SETO R6 SLA R8,4 A R10,R8 JMP GH1 GH2 MOV R6,R6 Reached end; do we have a number? JEQ GERR no, so that is an error GH3 MOV R6,R6 Whitespace; do we have a number? JEQ GH1 no, so continue skipping over WS MOV R8,@6(R13) Number in R8 goes to caller's R3 SOC @H2000,R15 was OK RTWP * Delivers the value of the hex digit in R10=000x, or FFFF if it is * not a hex digit HEXDIG CB R10,@H30 JL HEXD4 CB R10,@H39 JH HEXD1 SB @H30,R10 >34 - >30 = >04 JMP HEXD3 HEXD1 CI R10,>6000 JL HEXD2 AI R10,>E000 Make uppercase HEXD2 CB R10,@H41 JL HEXD4 CB R10,@H46 JH HEXD4 SB @H37,R10 >41 - >37 = >0A HEXD3 SRL R10,8 RT HEXD4 SETO R10 RT * ----- Direct argument ------- * has a value only; no name * R1 points to list of non-boolean flags * R3 is the target buffer (gets null termination) * ...yyyy.../x... * yyyy is the value * .../x...yyyy..zzzz * If x is non-boolean, zzzz is the value * If x is boolean, yyyy is the value GFD CLR R5 Slash mode GFD0 MOVB *R0+,R4 EOL JEQ GFD7 MOV R5,R5 Are we in slash mode JNE GFD4 MOVB R4,R10 not in value BL @WSPACE JEQ GFD0 skip WS CB R4,@SLASH No WS; it is a slash? JNE GFD3 Not a slash, not in value, not a whitespace SETO R5 Enter slash mode JMP GFD0 * Next character after slash in R4; check list * If the character is in the list, we have a valued parameter * If not, the option is boolean; continue searching GFD4 MOV R1,R3 List of non-boolean options GFD41 MOVB *R3+,R6 JEQ GFD End of list; continue searching CB R6,R4 JEQ GFD6 found CI R4,>6000 JH GFD41 char is lowercase and does not match AI R4,>2000 try to make it lowercase CB R6,R4 does it match? JNE GFD41 * Found the character in the list * If the next character is WS, skip all WS, then find the next WS * If not, find the next WS * Continue from above GFD6 MOVB *R0+,R10 EOL JEQ GFD7 BL @WSPACE JNE GFD63 GFD62 MOVB *R0+,R10 Skip all WS JEQ GFD7 BL @WSPACE JEQ GFD62 GFD63 MOVB *R0+,R10 Find the next WS JEQ GFD7 BL @WSPACE JNE GFD63 JMP GFD * Reached EOL before the option value was over, so there is no direct argument GFD7 SZC @H2000,R15 Reached EOL; not successful RTWP * Copy everything up to the next WS or EOL GFD3 MOV @6(R13),R1 DEC R0 GFD9 MOVB *R0+,R10 JEQ GFD10 BL @WSPACE JEQ GFD10 MOVB R10,*R1+ JMP GFD9 GFD10 CLR R10 MOVB R10,*R1+ Terminator SOC @H2000,R15 Got value RTWP END cliparse.dsk 9 Quote Link to comment Share on other sites More sharing options...
+dhe Posted October 6, 2022 Share Posted October 6, 2022 Thanks for the code. It's rare we get new well documented GeneveOS code. Command line parsing always seems like it's a trivial exercise, until you try it! 😃 I was looking at compiling (TIC) some Clint code but it was missing getargs_h - which isn't to be found. Of course, no telling if, at this point, all of his compiling was being done with TIC on another platform. 3 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted October 6, 2022 Author Share Posted October 6, 2022 I believe such a command line parser is a crucial requirement for writing programs for MDOS. Otherwise, we stay in the usual program design of the TI-99/4A, that is, design a user interface to input values during runtime. (Terminology: By MDOS I refer to the "shell" of the GeneveOS, i.e. the blue screen with white letters where you can load and run programs or commands.) 2 Quote Link to comment Share on other sites More sharing options...
+9640News Posted October 7, 2022 Share Posted October 7, 2022 4 hours ago, dhe said: Thanks for the code. It's rare we get new well documented GeneveOS code. Command line parsing always seems like it's a trivial exercise, until you try it! 😃 I was looking at compiling (TIC) some Clint code but it was missing getargs_h - which isn't to be found. Of course, no telling if, at this point, all of his compiling was being done with TIC on another platform. Have you looked for getargs_h in any of the TIC files within the 9640News diskettes? Just in the event the file was in there. 1 Quote Link to comment Share on other sites More sharing options...
+dhe Posted October 7, 2022 Share Posted October 7, 2022 29 minutes ago, 9640News said: Have you looked for getargs_h in any of the TIC files within the 9640News diskettes? Just in the event the file was in there. Yep. Quote Link to comment Share on other sites More sharing options...
+dhe Posted October 10, 2022 Share Posted October 10, 2022 I searched whtech from top to bottom. sitelist.txt is very helpful. 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.