ReadArgs() replaces equal (=) characters with spaces in command arguments even when there are no TEMPLATE keywords preceding the equal character. For example, if you copy or create a text file named big=large in ram: and change directory to ram: before entering this in a shell:
type big=large
you will get this output:
TYPE: Could not open input file "big".
TYPE: object not found
ReadArgs() shouldn't be replacing the equal character unless it's preceeded by a TEMPLATE keyword. We all know that we should place quotes around command arguments or filenames containing spaces or wildcard characters. However, the equal (=) character is not a wildcard and should work in an argument or filename without quotes.
ReadArgs bug
ReadArgs bug
AmigaOne X1000 with 2GB memory - OS4.1 FE
- colinw
- AmigaOS Core Developer
- Posts: 218
- Joined: Mon Aug 15, 2011 10:20 am
- Location: Brisbane, QLD. Australia.
Re: ReadArgs bug
****** dos.library/FindArg ************
*
* NAME
* FindArg - find a keyword in a template (V36)
*
* SYNOPSIS
* int32 index = FindArg(CONST_STRPTR template, CONST_STRPTR keyword);
*
* FUNCTION
* Returns the argument number of the keyword, or -1
* if it is not a keyword in the supplied template.
* Abbreviations are also compared.
*
* Template args are delimited by a comma, equals or slash ( , = / )
-> Template args are delimited by a comma, equals or slash ( , = / )
*
* INPUTS
* keyword - keyword to search for in template (case insensitive)
* template - template string to search
*
* RESULT
* index - entry number in template, or -1 if not found.
*
* NOTES
* From V50, this function is callable from tasks.
*
* BUGS
* In earlier published versions of the autodoc, keyword and template
* argument positions were reversed.
*
* SEE ALSO
* ReadArgs(), ReadLineItem(), FreeArgs()
*
************************************************************************
*
* NAME
* FindArg - find a keyword in a template (V36)
*
* SYNOPSIS
* int32 index = FindArg(CONST_STRPTR template, CONST_STRPTR keyword);
*
* FUNCTION
* Returns the argument number of the keyword, or -1
* if it is not a keyword in the supplied template.
* Abbreviations are also compared.
*
* Template args are delimited by a comma, equals or slash ( , = / )
-> Template args are delimited by a comma, equals or slash ( , = / )
*
* INPUTS
* keyword - keyword to search for in template (case insensitive)
* template - template string to search
*
* RESULT
* index - entry number in template, or -1 if not found.
*
* NOTES
* From V50, this function is callable from tasks.
*
* BUGS
* In earlier published versions of the autodoc, keyword and template
* argument positions were reversed.
*
* SEE ALSO
* ReadArgs(), ReadLineItem(), FreeArgs()
*
************************************************************************
Re: ReadArgs bug
I'm not sure it's ReadArgs doing anything special here, I think it might be the Shell. You get the same response when the equals is also appended to the command:xenic wrote:ReadArgs() replaces equal (=) characters with spaces in command arguments even when there are no TEMPLATE keywords preceding the equal character. For example, if you copy or create a text file named big=large in ram: and change directory to ram: before entering this in a shell:
type big=large
you will get this output:
TYPE: Could not open input file "big".
TYPE: object not found
Code: Select all
1.> type= big=large
TYPE: Could not open input file "big".
TYPE: object not found
Re: ReadArgs bug
It's not the shell. I discovered the problem because people were reporting "AmiStore" failing to send a correct URL through URLOpen to a browser. I ran some tests and discovered that if the URLOpen Commandline Format settings don't contain escaped quotes ("*"URL*"") the browser will receive a URL with the equal (=) characters replaced with spaces and display a blank window. Then I wrote a test program that gets the commandline arguments the C language way by accessing the argv array and by using ReadArgs(). The arguments from argv contain the equal characters as they should but arguments obtained with ReadArgs() have the equal characters replaced with spaces.chris wrote: I'm not sure it's ReadArgs doing anything special here, I think it might be the Shell.
You can even do "type=big" and it will be interpreted as "type big"
I think your "type=big" example reenforces my contention that all equal characters on a command line should not be stripped and replaced with spaces. Only equal signs preceeded by a TEMPLATE identifier should have equal characters removed. Given a file named "big=large" then the following command should delete the file big=large:
delete FILE=big=large
big Not Deleted: object not found
large Not Deleted: object not found
Instead you get the errors shown.
I'm not sure why Colin posted the FindArg() autodoc unless he's suggesting that programmers should use FindArg() instead of ReadArgs(). I think it's a little late for that since most Amiga programs already use ReadArgs().
Last edited by xenic on Mon Nov 17, 2014 3:59 am, edited 1 time in total.
AmigaOne X1000 with 2GB memory - OS4.1 FE
- colinw
- AmigaOS Core Developer
- Posts: 218
- Joined: Mon Aug 15, 2011 10:20 am
- Location: Brisbane, QLD. Australia.
Re: ReadArgs bug
I was apparently being somewhat too subtle, sorry.xenic wrote: I'm not sure why Colin posted the FindArg() autodoc unless he's suggesting that programmers should use FindArg() instead of ReadArgs().
ReadArgs() calls FindArg() and also ReadItem() to split out the template args. The delimiter characters that FindArg() uses means
they also affect the arguments for ReadArgs(). Also, ReadItem() separates equal signs out from arguments.
I highlit the section was halfway down the autodoc... -> Template args are delimited by a comma, equals or slash ( , = / )
It should work properly when you put the file name in double quotes, this will stop it being split.
ie; Delete FILE="big=large"
- thomasrapp
- Posts: 318
- Joined: Sun Jun 19, 2011 12:22 am
Re: ReadArgs bug
This has nothing to do with the problem. FindArg() examines the *template*, the thing like "PATH/A,ALL=RECURSIVE/S". This surely is delimited by , = and /. But it does not say anything about how ReadArgs() examines the *input string*. The input surely is *not* delimited by / for example, otherwise you wouldn't be able to enter paths.colinw wrote:I highlit the section was halfway down the autodoc... -> Template args are delimited by a comma, equals or slash ( , = / )
- colinw
- AmigaOS Core Developer
- Posts: 218
- Joined: Mon Aug 15, 2011 10:20 am
- Location: Brisbane, QLD. Australia.
Re: ReadArgs bug
The "input string" that ReadArgs() sees, is infact everything that was passed on the commandline, as one big string,thomasrapp wrote: This has nothing to do with the problem. FindArg() examines the *template*, the thing like "PATH/A,ALL=RECURSIVE/S".
This surely is delimited by , = and /. But it does not say anything about how ReadArgs() examines the *input string*.
The input surely is *not* delimited by / for example, otherwise you wouldn't be able to enter paths.
that being template keywords, equal signs, quoted args, paths and anything else to EOL. The ReadItem() function pulls
the "input string" apart, word by word, or quoted sections together, both the ReadItem() and FindArg() functions use
the same equals sign character as a "word" separator, the "words" are compared to the template keywords by using FindArg().
FindArgs() itterates over any delimiter characters to find any matching keyword, so if a keyword or an argument happens
to contain one of the delimiter character, then FindArg() will only compare the words either side of the delimiter.
So, you can't have keywords that contain the delimiter characters, neither can you have unquoted arguments with them.
Hence; "delete big=large" fails with "big" not found.
- thomasrapp
- Posts: 318
- Joined: Sun Jun 19, 2011 12:22 am
Re: ReadArgs bug
Agreed.colinw wrote:So, you can't have keywords that contain the delimiter characters,
That's just a matter of proper implementation.neither can you have unquoted arguments with them.
Re: ReadArgs bug
Yes you can. I think that's the point that thomasrapp was trying to make. The comma (,) and slash (/) delimiters are not removed from an unquoted argument. If I enter delete DH1:graphics/big,large on a command line, the file big,large will be deleted. The slash (/) and comma (,) delimiters aren't replaced by spaces. Neither should the equal (=) delimiter be replaced unless it's preceeded by a keyword as in FILE=. Obviously, you don't agree but I thought it would be worth mentioning the issue.colinw wrote:neither can you have unquoted arguments with them.
AmigaOne X1000 with 2GB memory - OS4.1 FE
- colinw
- AmigaOS Core Developer
- Posts: 218
- Joined: Mon Aug 15, 2011 10:20 am
- Location: Brisbane, QLD. Australia.
Re: ReadArgs bug
Yes you are right, I should have been more specific. The "them" should mean all equal sign characters.xenic wrote:Yes you can. I think that's the point that thomasrapp was trying to make. The comma (,) and slash (/) delimiters are not removedcolinw wrote:neither can you have unquoted arguments with them.
from an unquoted argument. ...
And yes, the template delimiters, (that are not also argument separators), do not cause a problem for arguments,
as they are not reserved characters for ReadItem(), only for FindArg().
FindArg() is only used to determine what "words" are keywords and what "words" are not.
The ReadItem() function is responsible for splitting the "words" within the line.
It's not that I don't agree, but these functions are just not that smart.xenic wrote:
Neither should the equal (=) delimiter be replaced unless it's preceeded by a keyword as in FILE=.
Obviously, you don't agree but I thought it would be worth mentioning the issue.
When I wrote the FindArg() and ReadItem() functions about 12 years ago, the requirement was to simply differentiate
what constituted a keyword versus what is an argument, and the other was to simply split the "words" from a string
based on simple delimiter rules and other criteria, like whether a "word" was actually an entire quoted section that
can also contain spaces and delimiters itself.
These also had to be 100% compatible with the old V40 68K assembly code versions.
As ReadArgs() is fed by "words" already split by ReadItem(), and FindArg() tells it whether a "word" is a keyword or not,
its job is to basically place what it is given, into an argument array, as requested.