Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!elroy.jpl.nasa.gov!ncar!midway!clout!chinet!tellab5!vpnet!orc From: orc@vpnet.chi.il.us (david parsons) Newsgroups: comp.sys.atari.st Subject: Re: TOS Command Line Message-ID: <1991May11.134908.29488@vpnet.chi.il.us> Date: 11 May 91 13:49:08 GMT References: Organization: Department of Atomic Text Units Lines: 176 In article steve@thelake.mn.org (Steve Yelvington) writes: [about the Atari approved extended argument passing regime] |If you need to pass more information than that, there are three currently |used methods, of which one, XARG, is currently endorsed by Atari Corp. Umm, xArgs is the scheme that Dale Schumacher, John Stanley, and yours truely came up with a while back. The MWC/Official Atari scheme is called ARGV or somesuch, I think, unless it suffered from name drift. Anticipating a future article, here's a example of code from my C library runtime startup that will, if properly #defined, deal with either or both of the standards (I was forced to implement the MWC Xarg scheme because I've started using MiNT on my machine, and MiNT gleefully stomps all over the user-accessable genealogy of each process. o / >--------X--snip snip snip------- O \ /* * initargs(), for use with libc (xArgs and/or mwcArgs) */ #include #define MWCARGS 1 #define XARGS 0 extern int _argc; /* argc/argv as globals, for easy access */ extern char **_argv; extern char *strtok(); #if MWCARGS extern char *_getenv(); #endif #if XARGS #include extern BASEPAGE *_base; extern char *getenv(); char xArgname[] = "xArg"; /* xArg environment (ick!) flag */ #endif _initargs(tail, size) char *tail; { register char *p; register i; #if XARGS if (p=getenv(xArgname)) { register struct xArg *xarg; register totalsize; register long addr; register char **args; for (addr=i=0; p[i]; i++) if (p[i] >= '0' && p[i] <= '9') addr = (addr<<4L) + (p[i]-'0'); else if (p[i] >= 'A' && p[i] <= 'F') addr = (addr<<4L) + (p[i]-'A'+10); else goto hackline; #if 0 if (addr&01L) /* a little bit of address checking... */ goto hackline; #endif xarg = (struct xArg *)addr; if (xarg->_xmagic == XMAGIC && xarg->_xparent == _base->p_parent) { #ifdef CORRUPT /* Use our parents dataspace - real nasty, eh? */ _argc = xarg->_xargc; _argv = xarg->_xargv; #else /* * Malloc() a bit of memory for the arguments * to hide in... */ totalsize = (1+xarg->_xargc) * sizeof(char *); for (i=0; i_xargc; i++) totalsize += 1+strlen(xarg->_xargv[i]); if ((_argv = (char **)Malloc((long)totalsize)) == 0L) _exit(-39); /* Out of memory - bye... */ _argc = xarg->_xargc; p = &_argv[1+xarg->_xargc]; for (args=xarg->_xargv, i=0; i_xargc; i++) { strcpy(_argv[i] = p, *args); p += 1+strlen(*args++); } _argv[i] = 0L; return; #endif } } #endif #if MWCARGS /* reference Atari Corp's standard document for argument passing */ if ((size = 127) && (p = _getenv("ARGV"))) { /* mwc args here */ register char *mwargv; /* truncate the environment here by making the A in ARGV into * a null */ *p++ = 0; /* advance to the next argument */ while (*p++) ; /* everything from this point on is arglist */ mwargv = p; _argc = 0; /* always room for one null argument */ /* * scan the arglist in a particularly perverse way: using *p++ * to scan for nulls will always leave us on the character after * the null: if that character is also null, we've hit the * double-null that shows the end of the arglist. */ while (*p) { while (*p++) ; _argc++; } if (_argv = (char **)Malloc((long)((1+_argc)*sizeof(char*)))) { for (i=0, p=mwargv; *p; i++) { _argv[i] = p; while (*p++) ; } _argv[i] = (char*)0; return; } _exit(-39); /* out of memory - bye! */ } #endif hackline: { char *tmpargs[63]; /* 125 chars max in cmdline; 63 args... */ /*tail[size] = 0;*/ /* paranoia... */ for (i=1, p=strtok(tail, "\t "); p; p=strtok(0L, "\t ")) tmpargs[i++] = p; _argc = i; if ((_argv = (char **)Malloc((long)(1+i)*sizeof(char *))) == 0L) _exit(-39); /* Out of memory - bye... */ _argv[i] = (char*)0; while (--i > 0) _argv[i] = tmpargs[i]; _argv[0] = "(none)"; } } /* initargs */ o / >--------X--snip snip snip------- O \ Note that the routine _getenv() works just like getenv(), except it returns the start of the environment string (ie: given the environment string "EDITOR=vi", getenv("EDITOR") returns a pointer to "vi" and _getenv("EDITOR") returns a pointer to "EDITOR=vi". _getenv() is a internal routine to my libc, so you'll haveta poke around the guts of your libc to find the corresponding routine, if it exists. __ .david parsons \/