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