|
|
1.1 ! root 1: /* ! 2: $VER: RKNOP's __main() 1.2 (06.02.95) ! 3: ! 4: Replacement AmigaDOS __main() for SAS/C 6.51. ! 5: ! 6: As with the standard __main(), this parses the input command line into the ! 7: argv array. However, here, the number of arguments is unlimited; ! 8: additionally, one may specify on the command line a list of arguments in ! 9: a file using the construction "@filename" (without quotes). The named file ! 10: will be read and all of the whitespace separated arguments therein will be ! 11: inserted to the argv array at that point. Since the string parser is written ! 12: recursively, embedded files may be nested; that is, within one filename ! 13: referenced on the command line with @, there may be another filename ! 14: referenced with @. Memory and stack space is the only limit as to how far ! 15: the nesting may go. ! 16: ! 17: Version 1.2 -- this version supports stderr redirection, similar to unix, by ! 18: specifying &filename (or & filename or &"file name" or & "file name") on the ! 19: command line. stderr is redirected by opening first calling Close() on what ! 20: is currently in __ufbs[2].ufbfh (hopefully this simulates the SAS stdio ! 21: destructor), and then Open()ing the file __ufbs[2].ufbfh with the specified ! 22: filename. ! 23: ! 24: Inspiration by Peter Simons. Rewritten from scratch by Robert Knop using no ! 25: SAS code so that this file could be freely distributed with PGP 2.6 ! 26: source code. ! 27: ! 28: [email protected] ! 29: [email protected] ! 30: R.KNOP1 on GEnie ! 31: */ ! 32: ! 33: #include <stdlib.h> ! 34: #include <stdio.h> ! 35: #include <string.h> ! 36: #include <ios1.h> ! 37: #include <dos/dos.h> ! 38: #include <exec/lists.h> ! 39: #include <exec/memory.h> ! 40: #include <exec/nodes.h> ! 41: #include <libraries/dos.h> ! 42: #include <libraries/dosextens.h> ! 43: #include <workbench/startup.h> ! 44: ! 45: #include <proto/dos.h> ! 46: #include <proto/exec.h> ! 47: ! 48: #define isspace(c) (((c)==' ')||((c)=='\t')||((c)=='\n')) ! 49: ! 50: extern struct WBStartup *_WBenchMsg; ! 51: ! 52: int main(int,void *); ! 53: int __regargs CountArgs(struct MinList *,struct ArgNode *); ! 54: void __regargs AddArgs(struct ArgNode **,char ***); ! 55: ! 56: struct ArgNode { ! 57: struct MinNode n; ! 58: int length; ! 59: char *d; ! 60: }; ! 61: ! 62: void __stdargs __main(char *inline) ! 63: { struct ArgNode n,*cur; ! 64: struct MinList ArgStrings; ! 65: int argc,rval; ! 66: char **argv,**pargv; ! 67: ! 68: NewList((struct List *)&ArgStrings); ! 69: n.d=inline; ! 70: AddTail((struct List *)&ArgStrings,(struct Node *)&n); ! 71: ! 72: if (inline && (argc=CountArgs(&ArgStrings,&n))) ! 73: { if (!(argv=(char **)calloc(argc+1,sizeof(char *)))) ! 74: /* +1 is for one null element at the end of argv */ ! 75: exit(20); ! 76: cur=&n; ! 77: pargv=argv; ! 78: AddArgs(&cur,&pargv); ! 79: } ! 80: else argv=(char **)_WBenchMsg; /* Workbench startup */ ! 81: ! 82: rval=main(argc,argv); ! 83: ! 84: /* Don't worry about cleanup -- we used only calloc & malloc */ ! 85: /* (It's safer this way, so that if the program goes directly to exit() ! 86: we don't have to worry about missed cleanup.) */ ! 87: ! 88: exit(rval); ! 89: } ! 90: ! 91: /**********************************************************************/ ! 92: /* CountArgs() -- a recursive function that counts the number of */ ! 93: /* arguments in the string in node.d. If, while */ ! 94: /* counting, it comes across an argument of the form */ ! 95: /* "@filename", it creates a new node on the tail of */ ! 96: /* list, reads the data from the named file */ ! 97: /* into this new node's data, and recursively calls */ ! 98: /* itself to count the arguments in the new read string*/ ! 99: /**********************************************************************/ ! 100: ! 101: int __regargs CountArgs(struct MinList *list,struct ArgNode *node) ! 102: { int argc; ! 103: struct ArgNode *n; ! 104: char *line,*fstart,fendbuffer; ! 105: BPTR ifp; /* Only 1 file will be open at a time */ ! 106: static struct FileInfoBlock fib; /* static safe for recursion */ ! 107: ! 108: argc=0; ! 109: line=node->d; ! 110: while (1) ! 111: { while (isspace(*line)) line++; /* Skip leading whitespace */ ! 112: ! 113: if (*line=='\0') break; ! 114: ! 115: else if (*line=='&') /* Skip a stderr redirect */ ! 116: { ++line; ! 117: while (isspace(*line)) ++line; ! 118: if (*line=='"') ! 119: { line++; ! 120: while (*line!='"' && *line!='\0') line++; ! 121: if (*line=='"') line++; ! 122: } ! 123: else ! 124: { while (!isspace(*line)) ! 125: { if (*line=='\0') break; ! 126: ++line; ! 127: } ! 128: } ! 129: } ! 130: ! 131: else if (*line=='@') /* Embedded file */ ! 132: { fstart=++line; ! 133: if (*line=='"') ! 134: { fstart++; line++; ! 135: while (*line!='"') ! 136: if (*(++line)=='\0') break; /* Errorish? */ ! 137: fendbuffer=*line; ! 138: *line='\0'; /* Temporarily 0-term so we can use as a filename */ ! 139: } ! 140: else ! 141: { while (!isspace(*line)) ! 142: if (*(++line)=='\0') break; /* Error? */ ! 143: fendbuffer=*line; ! 144: *line='\0'; /* Temp 0-term for filename */ ! 145: } ! 146: if (!(ifp=Open(fstart,MODE_OLDFILE))) ! 147: fprintf(stderr,"Couldn't open file \"%s\"\n",fstart); ! 148: else ! 149: { ExamineFH(ifp,&fib); ! 150: n=(struct ArgNode *)calloc(sizeof(struct ArgNode),1); ! 151: /* CHECK ERRORS!!!!!!!!!!! */ ! 152: AddTail((struct List *)list,(struct Node *)n); ! 153: if (fib.fib_Size) ! 154: { n->d=calloc((n->length=fib.fib_Size+1),1); ! 155: Read(ifp,n->d,fib.fib_Size); ! 156: n->d[fib.fib_Size]='\0'; /* Make sure null terminated */ ! 157: } ! 158: Close(ifp); ! 159: if (n->d) argc+=CountArgs(list,n); /* Recurse */ ! 160: } ! 161: *line=fendbuffer; /* Restore char replaced with '\0' */ ! 162: if (*line=='"') ++line; /* Increment line past quote */ ! 163: } /* End of embedded file handling */ ! 164: ! 165: else if (*line=='"') ! 166: { ++line; ! 167: while (*line!='"') ! 168: if (*(++line)=='\0') break; ! 169: argc++; ! 170: if (*line='"') ++line; ! 171: } ! 172: ! 173: else ! 174: { while (!isspace(*line)) ! 175: if (*(++line)=='\0') break; ! 176: argc++; ! 177: } ! 178: ! 179: } /* End of infinite loop */ ! 180: ! 181: return(argc); /* Also returns any nodes added to list from embed files */ ! 182: } ! 183: ! 184: /**********************************************************************/ ! 185: /* AddArgs() -- put each of the arguments in the node into the array */ ! 186: /* argv. Recurse if necessary */ ! 187: /**********************************************************************/ ! 188: ! 189: void __regargs AddArgs(struct ArgNode **node,char ***argv) ! 190: { char *line,*stderrfile; ! 191: ! 192: line=(*node)->d; ! 193: (*node)=(struct ArgNode*)(*node)->n.mln_Succ; ! 194: while (1) ! 195: { while (isspace(*line)) line++; /* Skip leading whitespace */ ! 196: ! 197: if (*line=='\0') break; /* Finished */ ! 198: ! 199: else if (*line=='&') /* stderr redirect */ ! 200: { ++line; ! 201: while (isspace(*line)) ++line; ! 202: if (*line=='"') ! 203: { stderrfile=++line; ! 204: while (*line!='"' && *line!='\0') line++; ! 205: if (*line=='"') { *line='\0'; line++; } ! 206: } ! 207: else ! 208: { stderrfile=line; ! 209: while (!isspace(*line)) ! 210: { if (*line=='\0') break; ! 211: line++; ! 212: } ! 213: if (*line!='\0') { *line='\0'; line++; } ! 214: } ! 215: Close(__ufbs[2].ufbfh); ! 216: if ((__ufbs[2].ufbfh=Open(stderrfile,MODE_NEWFILE))==NULL) ! 217: __ufbs[2].ufbfh=Open("NIL:",MODE_OLDFILE); ! 218: } ! 219: ! 220: else if (*line=='@') /* Embedded file -- skip past filename */ ! 221: { ++line; ! 222: if (*line=='"') ! 223: { while (*line!='"') ! 224: if (*(++line)=='\0') break; ! 225: } ! 226: else ! 227: { while (!isspace(*line)) ! 228: if (*(++line)=='\0') break; ! 229: } ! 230: AddArgs(node,argv); /* Add the arguments from whatever node */ ! 231: if (*line!='\0') ++line; ! 232: } ! 233: ! 234: else if (*line=='"') ! 235: { (*argv)[0]=++line; ! 236: while (*line!='"') ! 237: if (*(++line)=='\0') break; ! 238: if (*line!='\0') ! 239: { *line='\0'; /* Null terminate this argument */ ! 240: ++line; ! 241: } ! 242: (*argv)++; ! 243: } ! 244: ! 245: else ! 246: { (*argv)[0]=line; ! 247: while (!isspace(*line)) ! 248: if (*(++line)=='\0') break; ! 249: if (*line!='\0') ! 250: { *line='\0'; /* Null terminate this argument */ ! 251: ++line; ! 252: } ! 253: (*argv)++; ! 254: } ! 255: } /* End of infinite loop */ ! 256: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.