home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 208_01 / xmain.c < prev   
Text File  |  1987-10-13  |  6KB  |  293 lines

  1. /* xmain.c
  2.  *    called by the C program starter s.s
  3.  *    eventually calls main()
  4.  *    handles argv,argc,quotes,upper/lowercase,redirections
  5.  */
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <osif.h>
  9.  
  10.  
  11. #define EOLINE 0
  12. #define T_LT 1
  13. #define INDQUOTE 2
  14. #define INWORD 3
  15. #define T_GTGT 4
  16. #define T_GT 5
  17. #define T_WORD 6
  18. #define NEUTRAL 7
  19. #define INSQUOTE 8
  20. #define T_SQWORD 9
  21.  
  22. #define GETC() *cptr++
  23. #define UNGETC(c) cptr--
  24.  
  25. static char *cptr;
  26.  
  27. static int argc=0;
  28. static char **argv;
  29. static char *argl;
  30. extern char __tname[];
  31. extern char __pname[];
  32. extern char *index();
  33. extern char *malloc();
  34.  
  35. _main(com,len)
  36. char *com;
  37. {
  38. register char c;
  39. register int token;
  40. int inputp,outputp;
  41. char word[130];
  42.  
  43.     _chinit(); /*initialise channels*/
  44.     open(__tname,0);    /* CON: */
  45.     open(__tname,1);
  46.     open(__tname,2);/*want to read stderr*/
  47.  
  48.     com[len]=0;
  49.     cptr=com; argl=0; inputp=outputp=0;
  50.     strcpy(word,__pname);token=T_WORD; /*argv[0]*/
  51.     do {
  52.         switch(token){
  53.         case T_WORD:
  54.             addargv(word);
  55.             break;
  56.         case T_SQWORD:
  57.             ADDarg(word);
  58.             break;
  59.         case T_LT:
  60.             if(inputp){
  61.                 fprintf(stderr,"extra <\n");
  62.                 exit(1);
  63.             }
  64.             inputp++;
  65.             if(gettoken(word) == T_WORD) {
  66.                 close(0);
  67.                 if(open(word,0)==0)
  68.                     break;
  69.             }
  70.             fprintf(stderr,"cannot redirect input\n");
  71.             exit(1);
  72.         case T_GT:
  73.         case T_GTGT:
  74.             if(outputp){
  75.                 fprintf(stderr,"extra > or >>\n");
  76.                 exit(1);
  77.             }
  78.             outputp++;
  79.             if(gettoken(word)== T_WORD ) {
  80.                 close(1);
  81.                 if(open(word,1) == 1 || creat(word,0666) == 1){
  82.                     if(token==T_GTGT)lseek(1,0L,2);
  83.                     break;
  84.                 }
  85.             }
  86.             fprintf(stderr,"output redirection error\n");
  87.             exit(1);
  88.         }
  89.         token=gettoken(word);
  90.     } while(token!= EOLINE);
  91.  
  92.     makeargv();
  93.  
  94.     exit(main(argc,argv,(char *)0)); /* environment ptr nil */
  95. }
  96.  
  97. static gettoken(word)
  98. char *word;
  99. {
  100. register int state=NEUTRAL;
  101. register int c;
  102. register char *w;
  103. int slash=0;
  104. int qflag=0;
  105.     w= word;
  106.     for(;;) {
  107.         c= GETC();
  108.         switch(state) {
  109.         case NEUTRAL:
  110.             switch(c){
  111.             case ' ': case '\t':
  112.                 continue;
  113.             case '<':
  114.                 return(T_LT);
  115.             case '>':
  116.                 if((c= GETC())== '>')
  117.                     return(T_GTGT);
  118.                 UNGETC(c);
  119.                 return(T_GT);
  120.             case '\'':
  121.                 state=INSQUOTE; continue;
  122.             case '"':
  123.                 state=INDQUOTE; continue;
  124.             case EOLINE:
  125.                 UNGETC(c);
  126.                 return(EOLINE);
  127.             default:
  128.                 state=INWORD;
  129.                 if(c=='\\')
  130.                     slash++;
  131.                 else
  132.                     *w++ = tolower(c);
  133.                 continue;
  134.             }/* endsw inside case NEUTRAL*/
  135.         case INDQUOTE:
  136.         case INSQUOTE:
  137.             if(c==EOLINE){ *w=0;
  138.                 fprintf(stderr,"unmatched quote: %s\n",word);
  139.                 exit(1);
  140.             }
  141.             if(slash) {
  142.                 slash=0;
  143.                 *w++ = c;
  144.                 continue;
  145.             }
  146.             if(c== '\\'){
  147.                 slash++;
  148.                 continue;
  149.             }
  150.             if(c=='\'')
  151.                 if (state==INDQUOTE) {
  152.                     if(qflag==0)
  153.                         qflag++;
  154.                     else
  155.                         qflag=0;
  156.                     continue;
  157.                     }
  158.                 else {
  159.                     *w = '\0';return(T_SQWORD);
  160.                 }
  161.  
  162.             if(c== '"' && state==INDQUOTE && qflag==0) {
  163.                 *w = '\0';
  164.                 return(T_WORD);
  165.             }
  166.             *w++ = tolower(c);
  167.             continue;
  168.         case INWORD:
  169.             if(c==EOLINE){
  170.                 UNGETC(c);
  171.                 *w= '\0';
  172.                 return(T_WORD);
  173.             }
  174.             if(slash){
  175.                 slash=0;
  176.                 *w++ = c; continue;
  177.             }
  178.             if(c== '\\') {
  179.                 slash++; continue;
  180.             }
  181.             if(index("&();<> \t|",c)) {
  182.                 UNGETC(c);
  183.                 *w = '\0';
  184.                 return(T_WORD);
  185.             }
  186.             *w++ = tolower(c);
  187.             continue;
  188.         }/*endsw of state*/
  189.     }/*end of FOR*/
  190. }
  191.  
  192. /* we are going to use the file control block area allocated for
  193.  * the file descriptor 3. If you do not like this, you must set
  194.  * char dma[128]; char fcb[36]; to call search for first etc.
  195.  * NB you cannot call malloc() while you are arbitrarily breaking
  196.  * _break.
  197.  */
  198. static
  199. addargv(ptr)
  200. register char *ptr;
  201. {
  202. register char c;
  203. struct ccb *pfd;
  204. char tmpbuf[30];
  205.     if(index(ptr,'*')||index(ptr,'?')) {
  206.         /*NOSTRICT*/
  207.         pfd= _getccb(3); /* use the buffer of FD 3 */
  208.         __BDOS(26, pfd->buffer);
  209.         c= __open(3,ptr,17); /* search for first */
  210.         if(c != '\377')
  211.             for(;;){
  212.                 _toasc(pfd,c,tmpbuf);
  213.                 ADDarg(tmpbuf);
  214.                 c= __open(3,ptr,18); /* search for nxt */
  215.                 if(c == '\377')return;
  216.             }
  217.     }
  218.     ADDarg(ptr);
  219. }
  220. static
  221. memfault()
  222. {
  223. fprintf(stderr,"out of memory\n");
  224. exit(1);
  225. }
  226.  
  227. static
  228. ADDarg(ptr)
  229. register char *ptr;
  230. {
  231. register char **p;
  232.     /* make a list of ptr->back + strings */
  233.     if((p= (char **)malloc(sizeof(char *)+strlen(ptr)+1))==0)
  234.         memfault();
  235.     *p = argl;
  236.     argl=p;
  237.     strcpy((char *)&p[1],ptr);
  238.     argc++;
  239. }
  240. static
  241. makeargv()
  242. {
  243. register char **p;
  244. register int i;
  245.     if((argv=(char **)malloc((1+argc)* sizeof(char *)))==0)
  246.         memfault();
  247.     p= argl; i=argc;argv[i--]=0;
  248.     do {
  249.         argv[i]= p+1;
  250.         p = *p;
  251.     } while(i--);
  252. }
  253.  
  254. static
  255. _toasc(p,c,buf)
  256. register struct ccb *p;
  257. register char c;    /* c*32 gives position in the buffer */
  258. register char *buf;
  259. {
  260.     register char *f;
  261.     int i;
  262.     *buf=0;
  263.     i=0;
  264.     f= p->buffer;
  265.     f += c*32;
  266.     if(p->user) {
  267.         i=p->user-1;
  268.         if(i>=10)
  269.             *buf++ = '1';
  270.         *buf++ = i%10+'0';
  271.         *buf++ = ':';
  272.         i=1;
  273.     }
  274.     if(p->fcb.drive) {
  275.         if(i)
  276.             buf--;
  277.         *buf++ = p->fcb.drive +'a'-1;
  278.         *buf++ = ':';
  279.     }
  280.     for(i=1;i<9;i++)
  281.         if(f[i] !=' ')
  282.             *buf++ = tolower(toascii(f[i]));
  283.         else break;
  284.     *buf++ = '.';
  285.     for(i=9;i<12;i++)
  286.         if(f[i] !=' ')
  287.             *buf++ = tolower(toascii(f[i]));
  288.         else break;
  289.     if(buf[-1]== '.')buf--;
  290.     *buf= 0;
  291. }
  292.  
  293.