Home | History | Annotate | Line # | Download | only in dosboot
      1  1.1  rin /*	$NetBSD: doscommain.c,v 1.1 2024/06/29 13:45:14 rin Exp $	*/
      2  1.1  rin 
      3  1.1  rin /*
      4  1.1  rin  * Copyright (c) 1996
      5  1.1  rin  *	Matthias Drochner.  All rights reserved.
      6  1.1  rin  *
      7  1.1  rin  * Redistribution and use in source and binary forms, with or without
      8  1.1  rin  * modification, are permitted provided that the following conditions
      9  1.1  rin  * are met:
     10  1.1  rin  * 1. Redistributions of source code must retain the above copyright
     11  1.1  rin  *    notice, this list of conditions and the following disclaimer.
     12  1.1  rin  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  rin  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  rin  *    documentation and/or other materials provided with the distribution.
     15  1.1  rin  *
     16  1.1  rin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  1.1  rin  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  1.1  rin  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  1.1  rin  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  1.1  rin  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  1.1  rin  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  1.1  rin  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  1.1  rin  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  1.1  rin  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  1.1  rin  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  1.1  rin  *
     27  1.1  rin  */
     28  1.1  rin 
     29  1.1  rin /* argument line processing for DOS .COM programs */
     30  1.1  rin 
     31  1.1  rin #include <lib/libsa/stand.h>
     32  1.1  rin 
     33  1.1  rin /* The Program Segment Prefix */
     34  1.1  rin 
     35  1.1  rin static struct psp{
     36  1.1  rin 	char mist1[0x2c];
     37  1.1  rin 	short envseg;
     38  1.1  rin 	char mist2[0x80-2-0x2c];
     39  1.1  rin 	char cmdlen;
     40  1.1  rin 	char cmd[127];
     41  1.1  rin } *PSP = (struct psp*)0;
     42  1.1  rin 
     43  1.1  rin static char* argv[64]; /* theor max */
     44  1.1  rin 
     45  1.1  rin static int whitespace(char);
     46  1.1  rin 
     47  1.1  rin static int
     48  1.1  rin whitespace(char c)
     49  1.1  rin {
     50  1.1  rin 	if ((c == '\0') || (c == ' ') || (c == '\t')
     51  1.1  rin 	    || (c == '\r') || (c == '\n'))
     52  1.1  rin 		return (1);
     53  1.1  rin 	return 0;
     54  1.1  rin }
     55  1.1  rin 
     56  1.1  rin enum state {skipping, doing_arg, doing_long_arg};
     57  1.1  rin 
     58  1.1  rin /* build argv/argc, start real main() */
     59  1.1  rin int doscommain(void);
     60  1.1  rin extern int main(int, char**);
     61  1.1  rin 
     62  1.1  rin int
     63  1.1  rin doscommain(void)
     64  1.1  rin {
     65  1.1  rin 	int argc, i;
     66  1.1  rin 	enum state s;
     67  1.1  rin 
     68  1.1  rin 	argv[0] = "???"; /* we don't know */
     69  1.1  rin 	argc = 1;
     70  1.1  rin 	s = skipping;
     71  1.1  rin 
     72  1.1  rin 	for (i = 0; i < PSP->cmdlen; i++){
     73  1.1  rin 
     74  1.1  rin 		if (whitespace(PSP->cmd[i])) {
     75  1.1  rin 			if (s == doing_arg) {
     76  1.1  rin 				/* end of argument word */
     77  1.1  rin 				PSP->cmd[i] = '\0';
     78  1.1  rin 				s = skipping;
     79  1.1  rin 			}
     80  1.1  rin 			continue;
     81  1.1  rin 		}
     82  1.1  rin 
     83  1.1  rin 		if (PSP->cmd[i] == '"') {
     84  1.1  rin 			/* start or end long arg
     85  1.1  rin 			 * (end only if next char is whitespace)
     86  1.1  rin 			 *  XXX but '" ' cannot be in argument
     87  1.1  rin 			 */
     88  1.1  rin 			switch (s) {
     89  1.1  rin 			case skipping:
     90  1.1  rin 				/* next char begins new argument word */
     91  1.1  rin 				argv[argc++] = &PSP->cmd[i + 1];
     92  1.1  rin 				s = doing_long_arg;
     93  1.1  rin 				break;
     94  1.1  rin 			case doing_long_arg:
     95  1.1  rin 				if (whitespace(PSP->cmd[i + 1])) {
     96  1.1  rin 					PSP->cmd[i] = '\0';
     97  1.1  rin 					s = skipping;
     98  1.1  rin 				}
     99  1.1  rin 			case doing_arg:
    100  1.1  rin 				/* ignore in the middle of arguments */
    101  1.1  rin 			default:
    102  1.1  rin 				break;
    103  1.1  rin 			}
    104  1.1  rin 			continue;
    105  1.1  rin 		}
    106  1.1  rin 
    107  1.1  rin 		/* all other characters */
    108  1.1  rin 		if (s == skipping) {
    109  1.1  rin 			/* begin new argument word */
    110  1.1  rin 			argv[argc++] = &PSP->cmd[i];
    111  1.1  rin 			s = doing_arg;
    112  1.1  rin 		}
    113  1.1  rin 	}
    114  1.1  rin 	if (s != skipping)
    115  1.1  rin 		PSP->cmd[i] = '\0'; /* to be sure */
    116  1.1  rin 
    117  1.1  rin 	/* start real main() */
    118  1.1  rin 	return main(argc, argv);
    119  1.1  rin }
    120