xref: /netbsd-src/sys/arch/acorn32/stand/lib/srt1.c (revision 02cdf4d2c869ecfa1ae5484cf77eefe2fbcc6d94)
1*02cdf4d2Sdsl /*	$NetBSD: srt1.c,v 1.6 2009/03/14 14:45:52 dsl Exp $	*/
246dbb0f2Sreinoud 
346dbb0f2Sreinoud /*
446dbb0f2Sreinoud  * Copyright (c) 2001 Ben Harris.
546dbb0f2Sreinoud  * Copyright (c) 1996
646dbb0f2Sreinoud  *	Matthias Drochner.  All rights reserved.
746dbb0f2Sreinoud  *
846dbb0f2Sreinoud  * Redistribution and use in source and binary forms, with or without
946dbb0f2Sreinoud  * modification, are permitted provided that the following conditions
1046dbb0f2Sreinoud  * are met:
1146dbb0f2Sreinoud  * 1. Redistributions of source code must retain the above copyright
1246dbb0f2Sreinoud  *    notice, this list of conditions and the following disclaimer.
1346dbb0f2Sreinoud  * 2. Redistributions in binary form must reproduce the above copyright
1446dbb0f2Sreinoud  *    notice, this list of conditions and the following disclaimer in the
1546dbb0f2Sreinoud  *    documentation and/or other materials provided with the distribution.
1646dbb0f2Sreinoud  *
1746dbb0f2Sreinoud  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1846dbb0f2Sreinoud  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1946dbb0f2Sreinoud  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2046dbb0f2Sreinoud  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2146dbb0f2Sreinoud  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2246dbb0f2Sreinoud  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2346dbb0f2Sreinoud  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2446dbb0f2Sreinoud  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2546dbb0f2Sreinoud  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2646dbb0f2Sreinoud  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2746dbb0f2Sreinoud  */
2846dbb0f2Sreinoud 
2946dbb0f2Sreinoud /* Command-line parsing from i386 doscommain.c */
3046dbb0f2Sreinoud 
31f9188e92Smatt #include <lib/libkern/libkern.h>
3246dbb0f2Sreinoud #include <lib/libsa/stand.h>
3346dbb0f2Sreinoud #include <riscoscalls.h>
3446dbb0f2Sreinoud #include <srt0.h>
3546dbb0f2Sreinoud 
3646dbb0f2Sreinoud 
3746dbb0f2Sreinoud /* limit of the memory given to us by RISC OS's WIMPslot; inited by srt0.S */
3846dbb0f2Sreinoud /* init it also to a reasonable value also so it doesnt get into the BSS ! */
3946dbb0f2Sreinoud void *HIMEM = (void *) 0x12000;
4046dbb0f2Sreinoud 
4146dbb0f2Sreinoud 
42*02cdf4d2Sdsl static int whitespace(char);
4346dbb0f2Sreinoud 
whitespace(char c)4446dbb0f2Sreinoud static int whitespace(char c) {
4546dbb0f2Sreinoud 	if ((c == '\0') || (c == ' ') || (c == '\t')
4646dbb0f2Sreinoud 	    || (c == '\r') || (c == '\n'))
4746dbb0f2Sreinoud 		return (1);
4846dbb0f2Sreinoud 	return (0);
4946dbb0f2Sreinoud }
5046dbb0f2Sreinoud 
5146dbb0f2Sreinoud 
5246dbb0f2Sreinoud enum state {skipping, doing_arg, doing_long_arg};
5346dbb0f2Sreinoud 
5446dbb0f2Sreinoud 
5546dbb0f2Sreinoud /* build argv/argc, start real main() */
5646dbb0f2Sreinoud void __start(void);
5746dbb0f2Sreinoud int splitargs(char *, int, char**);
5846dbb0f2Sreinoud extern int main(int, char**);
5946dbb0f2Sreinoud 
6046dbb0f2Sreinoud extern char edata[], end[];
6146dbb0f2Sreinoud 
6246dbb0f2Sreinoud 
6346dbb0f2Sreinoud void
__start(void)6446dbb0f2Sreinoud __start(void)
6546dbb0f2Sreinoud {
6646dbb0f2Sreinoud 	int argc;
677cffe838Sreinoud 	char *ro_args, *args, **argv;
6846dbb0f2Sreinoud 
6946dbb0f2Sreinoud 	/* Clear BSS */
7046dbb0f2Sreinoud 	memset(edata, 0, end - edata);
7146dbb0f2Sreinoud 
7246dbb0f2Sreinoud 	/* Define heap. */
7346dbb0f2Sreinoud 	setheap(end, (void *)(HIMEM - 0x1000));
7446dbb0f2Sreinoud 
757cffe838Sreinoud 	ro_args = os_get_env(NULL, NULL);
767cffe838Sreinoud 
777cffe838Sreinoud 	args = alloc(strlen(ro_args)+10);	/* some spare extra */
787cffe838Sreinoud 	strcpy(args, ro_args);
7946dbb0f2Sreinoud 
8046dbb0f2Sreinoud 	argc = splitargs(args, 0, NULL);
8146dbb0f2Sreinoud 	argv = alloc(argc * sizeof(*argv));
8246dbb0f2Sreinoud 	if (argv == NULL)
8346dbb0f2Sreinoud 		panic("alloc of argv failed");
8446dbb0f2Sreinoud 	argc = splitargs(args, 1, argv);
8546dbb0f2Sreinoud 
8646dbb0f2Sreinoud 	/* start real main() */
8746dbb0f2Sreinoud 	os_exit(NULL, main(argc, argv));
8846dbb0f2Sreinoud }
8946dbb0f2Sreinoud 
9046dbb0f2Sreinoud int
splitargs(char * args,int really,char ** argv)9146dbb0f2Sreinoud splitargs(char *args, int really, char **argv)
9246dbb0f2Sreinoud {
9346dbb0f2Sreinoud 	int argc, i;
9446dbb0f2Sreinoud 	enum state s;
9546dbb0f2Sreinoud 
9646dbb0f2Sreinoud 	argc = 0;
9746dbb0f2Sreinoud 	s = skipping;
9846dbb0f2Sreinoud 
9946dbb0f2Sreinoud 	for (i = 0; args[i]; i++){
10046dbb0f2Sreinoud 
10146dbb0f2Sreinoud 		if (whitespace(args[i])) {
10246dbb0f2Sreinoud 			if (s == doing_arg) {
10346dbb0f2Sreinoud 				/* end of argument word */
10446dbb0f2Sreinoud 				if (really)
10546dbb0f2Sreinoud 					args[i] = '\0';
10646dbb0f2Sreinoud 				s = skipping;
10746dbb0f2Sreinoud 			}
10846dbb0f2Sreinoud 			continue;
10946dbb0f2Sreinoud 		}
11046dbb0f2Sreinoud 
11146dbb0f2Sreinoud 		if (args[i] == '"') {
11246dbb0f2Sreinoud 			/* start or end long arg
11346dbb0f2Sreinoud 			 * (end only if next char is whitespace)
11446dbb0f2Sreinoud 			 *  XXX but '" ' cannot be in argument
11546dbb0f2Sreinoud 			 */
11646dbb0f2Sreinoud 			switch (s) {
11746dbb0f2Sreinoud 			case skipping:
11846dbb0f2Sreinoud 				/* next char begins new argument word */
11946dbb0f2Sreinoud 				if (really)
12046dbb0f2Sreinoud 					argv[argc] = &args[i + 1];
12146dbb0f2Sreinoud 				argc++;
12246dbb0f2Sreinoud 				s = doing_long_arg;
12346dbb0f2Sreinoud 				break;
12446dbb0f2Sreinoud 			case doing_long_arg:
12546dbb0f2Sreinoud 				if (whitespace(args[i + 1])) {
12646dbb0f2Sreinoud 					if (really)
12746dbb0f2Sreinoud 						args[i] = '\0';
12846dbb0f2Sreinoud 					s = skipping;
12946dbb0f2Sreinoud 				}
13046dbb0f2Sreinoud 				break;
13146dbb0f2Sreinoud 			case doing_arg:
13246dbb0f2Sreinoud 				/* ignore in the middle of arguments */
13346dbb0f2Sreinoud 			default:
13446dbb0f2Sreinoud 				break;
13546dbb0f2Sreinoud 			}
13646dbb0f2Sreinoud 			continue;
13746dbb0f2Sreinoud 		}
13846dbb0f2Sreinoud 
13946dbb0f2Sreinoud 		/* all other characters */
14046dbb0f2Sreinoud 		if (s == skipping) {
14146dbb0f2Sreinoud 			/* begin new argument word */
14246dbb0f2Sreinoud 			if (really)
14346dbb0f2Sreinoud 				argv[argc] = &args[i];
14446dbb0f2Sreinoud 			argc++;
14546dbb0f2Sreinoud 			s = doing_arg;
14646dbb0f2Sreinoud 		}
14746dbb0f2Sreinoud 	}
14846dbb0f2Sreinoud 	return argc;
14946dbb0f2Sreinoud }
15046dbb0f2Sreinoud 
_rtt(void)15146dbb0f2Sreinoud void _rtt(void)
15246dbb0f2Sreinoud {
15346dbb0f2Sreinoud 
15446dbb0f2Sreinoud 	os_exit(NULL, 0);
15546dbb0f2Sreinoud }
156