home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1998 February / PCOnline_02_1998.iso / filesbbs / os2 / pgp263.arj / PGP263I.SRC / PGP263II.ZIP / src / amiga__main.c < prev    next >
C/C++ Source or Header  |  1995-08-07  |  9KB  |  257 lines

  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.   rknop@netcom.com
  29.   rknop@citir5.caltech.edu
  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. }
  257.