ReadArgsNumber.c

/* compiles and runs, use -lauto  															*/
/* JosDuchIt                      															*/
/* ReadArgsNumber.c: how to print & use a numeric argument  				      */			
 
/*
 
For non-experienced programmers: 
I had some trouble understanding how ReadArgs() copes with numeric arguments.
 
This is where i got and how i got there. 
 
 
Refs:
Autodocs:dos.doc
---------------
struct RDArgs *result = ReadArgs(CONST_STRPTR template,
	                                 int32 *array, struct RDArgs *rdargs);
 
	To get the results of ReadArgs(), you examine the array of longwords
	( int32 *array ) you passed to it. 	(one entry per option in the template).
 
	Exactly what is put in a given entry by ReadArgs() depends on the 
	type of option. The default is a string (a sequence of non-whitespace
	characters, or delimited by quotes, which will be stripped by
	ReadArgs()), in which case the entry will be a pointer.
 
	/N - Number.  This parameter is considered a decimal integer, and will
	     be converted by ReadArgs.  If an invalid number is specified,
 
	   	an error will be returned.  
			The entry will be a pointer to the longword number 
			(this is how you know if a number was specified)
Exec/Types.h
------------
typedef   signed long  int32;
typedef  int32  LONG;
 
 
therefor the type of what is put in the array entry is: 
LONG * and you can acces its value with *array[i], i = 0,1....
or with  *(*(array + i)), i = 0,1,...
 
Or that is what i thought.
 
Inspiration:
----------- 
RKRM ADCD_2.1:Reference/HTML/AmigaMail_Vol2_guide/node0066.html
 
http://eu.os4depot.net/share/development/example/dostutorials.lha
DOS Tutorials/0 - Read Arguments/Project.c"
 
Tjitte Oldfart example Project.c  IDOS->Printf("INFO : Size < %lu >\n", *((uint32 *)*(Options + 2)));
*/
 
 
#define __USE_INLINE__
#include <exec/types.h>
#include <proto/dos.h> //ReadArgs,Printf
#include <stdio.h>
#include <string.h>
 
#define TEMPLATE  "LEFT/A/N"
 
int main(int argc, char *argv[]) {
 
	LONG	args[] = { 0 }; //=> equivalent to  LONG *args
 
	struct RDArgs *rdargs;
   int RC = RETURN_FAIL;
	rdargs = ReadArgs(TEMPLATE,args, NULL); //>>>>>>>>>>>>>>>>>>>>>
	if (rdargs == NULL){ 
    	PrintFault(IoErr(), NULL);
    	goto endprog;
	}
	if (args[0]) {
 
		//printf("1 %ld\n", *args[0]);   			/// invalid type argument of 'unary *'
		//printf("2 %ld\n", *(args[0])); 			/// invalid type argument of 'unary *'
		//printf("3 %ld\n", *(*args));   			/// invalid type argument of 'unary *'
		//printf("4 %ld\n", *(*(args))); 			/// invalid type argument of 'unary *'
		//printf("5 %ld\n", *((LONG)(*args)));		/// invalid type argument of 'unary *'
		//printf("6 %ld\n", *((LONG)(*(args))));	/// invalid type argument of 'unary *'
 
		  printf("%ld\n", args);    					/// value (independent of execution)
 
/*
1		1437510856
2		1437510856
1234	1437510856
 
*/
 
		  printf("%ld\n", args[0]);    				/// address1 (dependent on execution)
		  printf("%ld\n", *args);      				/// address1
		  printf("%ld\n", *(args));    				/// address1
		  printf("%ld\n", *(args+0));  				/// address1
 
/* all pointing  to the same "LONG" integer argument
 so we expect
LONG * args[0];
LONG * *args;
LONG * *(args);
LONG * *(args +0);
 
and therfor expect the LONG numbers to be
LONG *(args[0]);
LONG *(*args);
LONG *(*(args));
LONG *(*(args +0));
 
as printf("%ld", mylong);
expects mylong to be of LONG type
 
We did expect the following printf statements to work
 
*/
 
//printf("Logic 1 %ld\n",*(args[0]));		
//printf("Logic 2 %ld\n",*(*args));
//printf("Logic 3 %ld\n",*(*(args))
 
/* however they all get the error "invalid type argument of 'unary *'
This is because the type on which the unary works is not recognised 
as a pointer but as a LONG 
 
We can alter this though with the cast
(LONG *)
and thus
*(LONG *) preceding the 3 variants for the printf argument should
give the expected result 
 
 
*/
 
 
 
 
 
//some casts do not alter the printf output, and seem to be equivalent, but 
// only the (LONG *) casts bring us closer tot the solution
 
		  printf("e1 %ld\n", (LONG)*args);			/// address1
		  printf("e2 %ld\n", (LONG *)*args);		/// address1
 
		  printf("f1 %ld\n", (LONG)(*args));		/// address1
		  printf("f2 %ld\n", (LONG *)(*args));		/// address1
 
		  printf("g1 %ld\n", (LONG)(*(args)));		/// address1
		  printf("g2 %ld\n", (LONG *)(*(args)));	/// address1
 
// So all of the following work
 
		  printf("%lu\n", *((uint32 *)*(args+0)));	
		  printf("%ld\n", *((LONG *)*(args)));			
		  printf("%ld\n", *((LONG *)*args));			
		  printf("%ld\n", *((LONG *)(*args)));			
		  printf("%ld\n", *((LONG *)(*(args))));		
		  printf("%ld\n", *((LONG *)(args[0])));	   
 
// but also the following i discovered with trial and error
 
 
		  printf("%ld\n", (LONG *)*(LONG *)args[0]); 
		  printf("%ld\n", (LONG *)*(LONG *)*args);   
 
 
 
 
 
	}
 
 
 
 
 FreeArgs(rdargs);
 return (RETURN_OK); 
endprog:
 printf("%s\n", "sorry");
 FreeArgs(rdargs);
 return (RETURN_FAIL);
 
}