home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / gnuc / library / rcs / _cli_parse.c,v < prev    next >
Encoding:
Text File  |  1992-08-09  |  22.3 KB  |  807 lines

  1. head    1.3;
  2. access;
  3. symbols
  4.     version39-41:1.2;
  5. locks;
  6. comment    @ *  @;
  7.  
  8.  
  9. 1.3
  10. date    92.08.09.20.41.17;    author amiga;    state Exp;
  11. branches;
  12. next    1.2;
  13.  
  14. 1.2
  15. date    92.07.04.19.09.27;    author mwild;    state Exp;
  16. branches;
  17. next    1.1;
  18.  
  19. 1.1
  20. date    92.05.14.19.55.40;    author mwild;    state Exp;
  21. branches;
  22. next    ;
  23.  
  24.  
  25. desc
  26. @parse AmigaDOS commandline into argv[], do wildcard expansion
  27. @
  28.  
  29.  
  30. 1.3
  31. log
  32. @change to use 2.x header files by default
  33. @
  34. text
  35. @/*
  36.  *  This file is part of ixemul.library for the Amiga.
  37.  *  Copyright (C) 1991, 1992  Markus M. Wild
  38.  *
  39.  *  This library is free software; you can redistribute it and/or
  40.  *  modify it under the terms of the GNU Library General Public
  41.  *  License as published by the Free Software Foundation; either
  42.  *  version 2 of the License, or (at your option) any later version.
  43.  *
  44.  *  This library is distributed in the hope that it will be useful,
  45.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  46.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  47.  *  Library General Public License for more details.
  48.  *
  49.  *  You should have received a copy of the GNU Library General Public
  50.  *  License along with this library; if not, write to the Free
  51.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  52.  *
  53.  *  $Id: _cli_parse.c,v 1.2 1992/07/04 19:09:27 mwild Exp $
  54.  *
  55.  *  $Log: _cli_parse.c,v $
  56.  *  Revision 1.2  1992/07/04  19:09:27  mwild
  57.  *  make stderr (desc 2) *really* read/write, don't just say so...
  58.  *
  59.  * Revision 1.1  1992/05/14  19:55:40  mwild
  60.  * Initial revision
  61.  *
  62.  */
  63.  
  64. /*
  65.  *    This routine is called from the _main() routine and is used to
  66.  *    parse the arguments passed from the CLI to the program. It sets
  67.  *    up an array of pointers to arguments in the global variables and
  68.  *    and sets up _argc and _argv which will be passed by _main() to
  69.  *    the main() procedure. If no arguments are ever going to be
  70.  *    parsed, this routine may be replaced by a stub routine to reduce
  71.  *    program size.
  72.  *
  73.  *  ---------------
  74.  *
  75.  *  I modified this, so that if you set the variable
  76.  *  "expand_cmd_line", wildcards in the command-line will be expanded
  77.  *  according to ARP wildcard-rules. Normally, if you supply Wildcards
  78.  *  along with a path, you'd expect to get expanded filenames together
  79.  *  with their path, if you ONLY want to expand filenames, set the
  80.  *  variable "dont_expand_full_path_name".
  81.  *
  82.  *  Example: normally, ram:t/* will get you
  83.  *                ram:t/foo1 ram:t/foo2 ram:t/foo3 and so on
  84.  *  but if you set "dont_expand_full_path_name", you'll instead get:
  85.  *                foo1 foo2 foo3 and so on
  86.  *
  87.  *  1990-09-14 Markus Wild - first version
  88.  *  1990-11-04 Markus Wild - modified for use in own libc
  89.  *                           all Manx code removed, so now really free
  90.  *  1991-12-15 Markus Wild - Use 2.04 DOS ASL functions instead of the ARP
  91.  *                 stuff. They really *are* the ARP stuff ;-))
  92.  *  1991-12-30 Markus Wild - Converted into form used by shared library
  93.  *  1992-03-14 Markus Wild - Reenabled stdio code, now that stdio is in
  94.  *                 shared library. Added signal blocking.
  95.  */
  96.  
  97. #define KERNEL
  98. #include "ixemul.h"
  99.  
  100. #ifdef DEBUG
  101. #define DP(a) kprintf a
  102. #else
  103. #define DP(a)
  104. #endif
  105.  
  106. #include <dos/dosasl.h>
  107.  
  108. #include <stdio.h>
  109.  
  110. #define BASE_EXT_DECL
  111. #define BASE_PAR_DECL    
  112. #define BASE_PAR_DECL0    
  113. #define BASE_NAME    ix.ix_arp_base
  114. __inline static LONG FindFirst(BASE_PAR_DECL const char* pattern, struct AnchorPath* AnchorPath)
  115. {
  116.     BASE_EXT_DECL
  117.     register LONG res __asm("d0");
  118.     register void *a6 __asm ("a6");
  119.     register const char* d0 __asm("d0");
  120.     register struct AnchorPath* a0 __asm("a0");
  121.  
  122.     a6 = BASE_NAME;
  123.     d0 = pattern;
  124.     a0 = AnchorPath;
  125.     __asm volatile ("
  126.     jsr a6@@(-0x1b6)"
  127.     : "=r" (res)
  128.     : "r" (a6), "r" (d0), "r" (a0)
  129.     : "d0", "d1", "a0", "a1", "memory");
  130.     return res;
  131. }
  132. __inline static LONG FindNext(BASE_PAR_DECL struct AnchorPath* AnchorPath)
  133. {
  134.     BASE_EXT_DECL
  135.     register LONG res __asm("d0");
  136.     register void *a6 __asm ("a6");
  137.     register struct AnchorPath* a0 __asm("a0");
  138.  
  139.     a6 = BASE_NAME;
  140.     a0 = AnchorPath;
  141.     __asm volatile ("
  142.     jsr a6@@(-0x1bc)"
  143.     : "=r" (res)
  144.     : "r" (a6), "r" (a0)
  145.     : "d0", "d1", "a0", "a1", "memory");
  146.     return res;
  147. }
  148. __inline static void FreeAnchorChain(BASE_PAR_DECL struct AnchorPath* AnchorPath)
  149. {
  150.     BASE_EXT_DECL
  151.     register void *a6 __asm ("a6");
  152.     register struct AnchorPath* a0 __asm("a0");
  153.  
  154.     a6 = BASE_NAME;
  155.     a0 = AnchorPath;
  156.     __asm volatile ("
  157.     jsr a6@@(-0x1c2)"
  158.     : /* no output */
  159.     : "r" (a6), "r" (a0)
  160.     : "d0", "d1", "a0", "a1", "memory");
  161. }
  162.  
  163. #if __GNUC__ != 2
  164. #define alloca __builtin_alloca
  165. #endif
  166.  
  167. extern int _dos20;
  168.  
  169. #ifndef MAXPATHLEN
  170. #define MAXPATHLEN 1024
  171. #endif
  172.  
  173. extern int __read(), __write(), __ioctl(), __fselect(), __close();
  174.  
  175.  
  176. /* shudder what did they do.. with 2.04 patterns you have to specify ** instead
  177.  * of * to get what you really want, a match-all pattern. compatibility is
  178.  * something wonderful, but not this way! Get rid of it, QUICK ! */
  179. static inline const UBYTE *
  180. star_kludge (const char *patt)
  181. {
  182.   if (patt[0] == '*' && patt[1] == 0)
  183.     return (const UBYTE *) "**";
  184.   else
  185.     return (const UBYTE *) patt;
  186. }
  187.  
  188. /* We will store all arguments in this double linked list, the list
  189.  * is always sorted according to elements, ie. order of given arguments
  190.  * is preserved, but all elements, that get expanded will be sorted
  191.  * alphabetically in this list. */
  192.  
  193. struct ArgList {
  194.   struct MinList al_list;  /* the list - head */
  195.   long         al_num;   /* number of arguments in the whole list */
  196. };
  197.  
  198. struct Argument {
  199.   struct MinNode a_node;   /* the link in the arg-list */
  200.   char        *a_arg;       /* a malloc'd string, the argument */
  201. };
  202.  
  203. /* insert a new argument into the argument vector, we have to keep the
  204.  * vector sorted, but only element-wise, otherwise we would break the
  205.  * order of arguments, and "copy b a" is surely not the same as "copy a b"..
  206.  * so we don't scan the whole list, but start with element "start",
  207.  * if set, else we start at the list head */
  208.  
  209. static void 
  210. AddArgument (struct ArgList *ArgList,
  211.          struct Argument *start, struct Argument *arg, long size)
  212. {
  213.   register struct Argument *el, *nel;
  214.  
  215.   /* depending on "start", start scan for right position in list at
  216.    * successor of start or at head of list  */
  217.   for (el = (struct Argument *)
  218.         (start ? start->a_node.mln_Succ : ArgList->al_list.mlh_Head);
  219.        nel = (struct Argument *) el->a_node.mln_Succ;
  220.        el = nel)
  221.     if (strcmp (el->a_arg, arg->a_arg) > 0) break;
  222.  
  223.   Insert ((struct List *) ArgList, (struct Node *) arg, (struct Node *) el);
  224.  
  225.   /* and bump up the argument counter once */
  226.   ++ ArgList->al_num;
  227. }
  228.  
  229. /* if an argument contains one or more of these characters, we have to
  230.  * call the FindFirst/FindNext stuff, else don't bother expanding and
  231.  * quickly append to list. Here's the meaning of all these characters, some
  232.  * seem to be not widely used:
  233.  * *    match any number (incl. zero) of characters
  234.  * []   match any character that's contained in the set inside the brackets
  235.  * ?    match any character (exactly one)
  236.  * ~    negate the following expression
  237.  * #    match any number (incl. zero) of the following expression
  238.  * (|)  group expressions, the | seperates expressions, an empty expression
  239.  *      is legal
  240.  * %    the empty expression, can explicitely be given in groupings, 
  241.  *    eg. copy foo(%|1|2) ram: will copy the files foo, foo1 & foo2 into
  242.  *    the RAM disk. */
  243.  
  244. #if 0
  245. #define iswild(ch) ((ch=='*') || (ch=='[') || (ch==']') || (ch=='?') || \
  246.            (ch=='~') || (ch=='#') || (ch=='(') || (ch==')') || \
  247.            (ch=='|') || (ch=='%'))
  248. #else
  249. #define iswild(ch) (index ("*[]?~#()|%", ch) ? 1 : 0)
  250. #endif
  251.  
  252. void
  253. _cli_parse(struct Process *this_proc, long alen, char *_aptr,
  254.        int *argc, char ***argv)
  255. {
  256.   char *arg0;
  257.   struct CommandLineInterface *cli;
  258.   int c;
  259.   struct Argument *arg, *narg;
  260.   char *line, *next, *lmax, **cpp;
  261.   int do_expand, do_file_expand;
  262.   int arglen;
  263.   char *aptr;
  264.   struct AnchorPath *ap;
  265.   struct ArgList ArgList;
  266.   int expand_cmd_line = u.u_expand_cmd_line;
  267.   struct file *fin, *fout;
  268.   int fd;  
  269.   BPTR fh;
  270.   int omask;
  271.  
  272.   /* this stuff has been in ix_open before, but it really belongs here, since
  273.    * I don't want it to happen by default on OpenLibrary, since it would
  274.    * disturb any vfork() that wants to inherit files from its parent 
  275.    */
  276.  
  277.   omask = syscall (SYS_sigsetmask, ~0);
  278.   ix_lock_base ();
  279.  
  280.   if (! falloc (&fin, &fd))
  281.     {
  282.       /*
  283.        * NOTE: if there's an error creating one of the standard
  284.        *       descriptors, we just go on, the descriptor in
  285.        *       question will then not be set up, no problem ;-)
  286.        */
  287.       if (fd != 0)
  288.     ix_panic ("allocated stdin is not fd #0!");
  289.                
  290.       if (! falloc (&fout, &fd))
  291.     {
  292.       if (fd != 1)
  293.         ix_panic ("allocated stdout is not fd #1!");
  294.  
  295.       if (fh = Input ())
  296.         {
  297.           fin->f_name = "<Standard Input>";
  298.           fin->f_fh   = (struct FileHandle *)BTOCPTR(fh);
  299.           __init_std_packet(&fin->f_sp);
  300.           __fstat(fin);
  301.           fin->f_flags = FREAD|FEXTOPEN;
  302.           fin->f_type  = DTYPE_FILE;
  303.           fin->f_read  = __read;
  304.           fin->f_write = 0;
  305.           fin->f_ioctl = __ioctl;
  306.           fin->f_close = __close;
  307.           fin->f_select= __fselect;
  308.         }
  309.       else
  310.         {
  311.           u.u_ofile[0] = 0;
  312.           fin->f_count--;
  313.         }
  314.                     
  315.       if (fh = Output ())
  316.         {
  317.           fout->f_name = "<Standard Output>";
  318.           fout->f_fh   = (struct FileHandle *)BTOCPTR(fh);
  319.           __init_std_packet(&fout->f_sp);
  320.           __fstat(fout);
  321.           fout->f_flags = FWRITE|FEXTOPEN;
  322.           fout->f_type  = DTYPE_FILE;
  323.           fout->f_read  = 0;
  324.           fout->f_write = __write;
  325.           fout->f_ioctl = __ioctl;
  326.           fout->f_close = __close;
  327.           fout->f_select= __fselect;
  328.         }
  329.       else
  330.         {
  331.           u.u_ofile[1] = 0;
  332.           fout->f_count--;
  333.         }
  334.  
  335.       /* deal with stderr. Seems this was a last minute addition to 
  336.          dos 2, it's hardly documented, there are no access functions,
  337.          nobody seems to know what to do with pr_CES... */
  338.  
  339.       fd = -1;
  340.       if (_dos20 && ((fh = this_proc->pr_CES) || (fh = this_proc->pr_COS)))
  341.         {
  342.           struct file *fp;
  343.  
  344.           if (! falloc (&fp, &fd))
  345.             {
  346.           fp->f_name = "<Standard Error>";
  347.           fp->f_fh   = (struct FileHandle *)BTOCPTR(fh);
  348.           __init_std_packet(&fp->f_sp);
  349.           __fstat(fp);
  350.           fp->f_flags = FREAD|FWRITE|FEXTOPEN;
  351.           fp->f_type  = DTYPE_FILE;
  352.           fp->f_read  = __read;
  353.           fp->f_write = __write;
  354.           fp->f_ioctl = __ioctl;
  355.           fp->f_close = __close;
  356.           fp->f_select= __fselect;
  357.             }
  358.         }
  359.       if (fd == -1)
  360.         fd = open ("*", 2);
  361.  
  362.       if (fd > -1 && fd != 2)
  363.         {
  364.           dup2 (fd, 2);
  365.           close (fd);
  366.         }
  367.  
  368.     } /* falloc (&fout, &fd) */
  369.     } /* falloc (&fin, &fd) */
  370.  
  371.   ix_unlock_base ();
  372.   /* base unlocked, but signals still blocked */
  373.  
  374.   aptr = alloca (alen + 1);
  375.   bcopy (_aptr, aptr, alen + 1);
  376.  
  377.   cli = (struct CommandLineInterface *) BTOCPTR (this_proc->pr_CLI);
  378.   arg0 = (char *) BTOCPTR (cli->cli_CommandName);
  379.  
  380.   /* init our argument list */
  381.   NewList ((struct List *) &ArgList);
  382.   /* lets start humble.. no arguments at all:-)) */
  383.   ArgList.al_num = 0;
  384.  
  385.   /* we have to allocate
  386.    * enough space to carry even the weirdest path-names...
  387.    * memalign() is used, because struct Anchor contains a FileInfo
  388.    * block, and this one *has* to be long-aligned for DOS not to produce
  389.    * unpredictable things...
  390.    */
  391.   if (!expand_cmd_line)
  392.     ap = (struct AnchorPath *) syscall (SYS_memalign, 4, sizeof(*ap));
  393.   else
  394.     {
  395.       ap = (struct AnchorPath *) syscall (SYS_memalign, 4, sizeof(*ap)+MAXPATHLEN);
  396.       ap->ap_Strlen = MAXPATHLEN - 1;
  397.     }
  398.  
  399.   /* give the user a chance to break out of a neverending scan... */
  400.   ap->ap_BreakBits = SIGBREAKF_CTRL_C;
  401.   ap->ap_Flags = APF_DODOT;
  402.  
  403.   /* find end of command-line, stupid BCPL-stuff.. line can end
  404.    * either with \n or with \0 .. */
  405.   for (lmax = aptr; *lmax && *lmax != '\n' && *lmax != '\r'; ++lmax) ;
  406.   *lmax = 0;
  407.  
  408.   /* loop over all arguments, expand all */
  409.   for (line = aptr, narg = arg = 0; line < lmax; )
  410.     {
  411.       do_expand = 0;
  412.       do_file_expand = 0;
  413.  
  414.       /* skip over leading whitespace */
  415.       while (isspace (*line)) ++line;
  416.       if (line >= lmax) break;
  417.  
  418.       /* strange kind of BCPL-quoting, if you want to get a " thru,
  419.        * you have to quote it with a ', eq. HELLO'"WORLD'" will preserve
  420.        * the " inside the argument. Since hardly anyone knows this
  421.        * "feature", I allow for the more common Unix-like escaping, ie
  422.        * \" will give you the same effect as '". */
  423.       if ((*line == '\'' || *line == '\\') && line[1] == '\"')
  424.     {
  425.       ++line;
  426.       goto parsenormal;
  427.     }
  428.       /* if argument starts with ", don't expand it and remove the " */
  429.       else if (*line == '\"')
  430.     {
  431.       /* scan for end of quoted argument, this can be either at
  432.        * end of argumentline or at a second " */
  433.       ++line;
  434.       next = line;
  435.       while (next < lmax && *next != '\"')
  436.         {
  437.           /* prevent, that the loop terminates due to an escaped
  438.            * quote */
  439.           if ((*next == '\'' || *next == '\\') && next[1] == '\"')
  440.         {
  441.           /* in this case we have to shift the whole remaining
  442.            * line one position to the left to skip the 
  443.            * escape-character */
  444.           bcopy (next+1, next, (lmax - next) + 1);
  445.           --lmax;
  446.         }
  447.  
  448.           ++next;
  449.         }
  450.       *next = 0;
  451.     }
  452.       else
  453.     {
  454.       if (*line == '@@') do_file_expand = 1;
  455. parsenormal:
  456.       /* plain, vanilla argument.. */
  457.       next = line+1;
  458.       /* check, whether we have to run thru the expander, or
  459.        * if we rather can just copy over the whole argument */
  460.       do_expand = iswild (*line);
  461.       /* skip over element and make it 0-terminated .. */
  462.       while (next < lmax && !isspace (*next))
  463.         {
  464.           do_expand |= iswild (*next);
  465.           if ((*next == '\'' || *next == '\\') && next[1] == '\"')
  466.         {
  467.           bcopy (next+1, next, (lmax - next) + 1);
  468.           --lmax;
  469.         }
  470.  
  471.           ++next;
  472.         }
  473.       *next = 0;
  474.     }
  475.  
  476.       if (do_file_expand)
  477.     {
  478. #if 1
  479.       /* now that stdio is in the shared library, I can resort to the
  480.          old algorithm, and don't need the read() kludge below, hiphip ;-) */
  481.  
  482.       FILE *in;
  483.       char buf[1024], *cs, *ce;
  484.       
  485.       if (in = fopen (line+1, "r"))
  486.         {
  487.           while (!feof (in))
  488.         {
  489.           if (! fgets (buf, 1024, in)) break;
  490.           for (cs = buf;
  491.                isspace (*cs) && (cs < &buf[1024]);
  492.                ++cs) ;
  493.           for (ce = buf+(strlen(cs) - 1);
  494.                isspace(*ce) && (ce > buf);
  495.                *ce-- = 0) ;
  496.  
  497.           arg = (struct Argument *) malloc (sizeof (*arg));
  498.           arglen = strlen (cs);
  499.           arg->a_arg = (char *) malloc (arglen+1);
  500.           strcpy (arg->a_arg, cs);
  501.           AddArgument (&ArgList, narg, arg, arglen);
  502.           narg = arg;
  503.         }
  504.           fclose (in);
  505.         }
  506. #else
  507.       /* I don't want to use stdio at this point of the library. Since we
  508.        * know, that a file of this size is implemented with TYPE_MEMFILE
  509.        * anyway, we can just as well use sysio in this case */
  510.       int in;
  511.       char buf[1024], *cs, *ce;
  512.       
  513.       if ((in = syscall (SYS_open, line+1, 0)) >= 0)
  514.         {
  515.           for (;;)
  516.         {
  517.           /* simulate an fgets() */
  518.                 for (cs = buf;
  519.                syscall (SYS_read, in, cs, 1) == 1 && *cs++ != '\n'; ) ;
  520.                 if (cs == buf) break;
  521.                 *cs = 0;
  522.                 
  523.           for (cs = buf;
  524.                isspace (*cs) && (cs < &buf[1024]);
  525.                ++cs) ;
  526.           for (ce = buf+(strlen(cs) - 1);
  527.                isspace (*ce) && (ce > buf);
  528.                *ce-- = 0) ;
  529.         
  530.           arg = (struct Argument *) syscall (SYS_malloc, sizeof (*arg));
  531.           arglen = strlen (cs);
  532.           arg->a_arg = (char *) syscall (SYS_malloc, arglen+1);
  533.           strcpy (arg->a_arg, cs);
  534.           AddArgument (&ArgList, narg, arg, arglen);
  535.           narg = arg;
  536.         }
  537.  
  538.           syscall (SYS_close, in);
  539.         }
  540. #endif
  541.     }
  542.       else if (expand_cmd_line && do_expand)
  543.     {
  544.       int num_expand=0;
  545.  
  546.       ap->ap_FoundBreak = 0;
  547.       /* init the scanner */
  548.       if (! (_dos20 ? MatchFirst (star_kludge (line), ap) 
  549.             : FindFirst (line, ap)))
  550.         {
  551.           do
  552.         {
  553.           register char *name;
  554.  
  555.           /* signals are blocked, but we break this loop if one
  556.              is pending ! */
  557.              
  558.           if (u.p_sig) break;
  559.  
  560.           arg = (struct Argument *) syscall (SYS_malloc, sizeof (*arg));
  561.           /* where will the name be stored ?? */
  562.           name = ap->ap_Buf;
  563.           arglen = strlen (name);
  564.           arg->a_arg = (char *) syscall (SYS_malloc, arglen+1);
  565.           strcpy (arg->a_arg, name);
  566.           AddArgument (&ArgList, narg, arg, arglen);
  567.           ++num_expand;
  568.           /* we do this as long as there are no errors. I
  569.            * don't care WHICH error will terminate the loop,
  570.            * if the regular ERROR_NO_MORE_ENTRIES, or some
  571.            * real error. */
  572.         }
  573.           while (! (_dos20 ? MatchNext (ap) : FindNext (ap)));
  574.           /* after we're done with the work, we have to free
  575.            * the whole anchor-list, to make it usable again
  576.            * for a new argument */
  577.           if (_dos20)
  578.         MatchEnd (ap);
  579.           else
  580.         FreeAnchorChain (ap);
  581.         }
  582.  
  583.       /* if break, really break.. stop scanning arguments...*/
  584.       if (ap->ap_FoundBreak || u.p_sig)
  585.         {
  586.           syscall (SYS_sigsetmask, omask);    /* this might already abort.. */
  587.           syscall (SYS_write, 2, (UBYTE *) "^C\n", 3);
  588.           syscall (SYS__exit, 20);
  589.         }
  590.  
  591.       /* simulate Unix sh, if there was a wildcard in the
  592.        * argument, but it didn't expand into anything, pass the
  593.        * original argument to the program. Csh on the other hand
  594.        * just outputs an error-msg "no match", but I think this
  595.        * should be handled by the program... */
  596.       if (!num_expand) goto vanilla_arg;
  597.     }
  598.       else  /* ! do_expand */
  599.     {
  600. vanilla_arg:
  601.       /* just add the argument "as is" */
  602.       arg = (struct Argument *) syscall (SYS_malloc, sizeof (*arg));
  603.       arglen = strlen (line);
  604.       arg->a_arg = (char *) syscall (SYS_malloc, arglen+1);
  605.       strcpy (arg->a_arg, line);
  606.       AddArgument (&ArgList, narg, arg, arglen);
  607.     }
  608.  
  609.       narg = (struct Argument *) ArgList.al_list.mlh_TailPred;
  610.       line = next+1;
  611.     } /* for */
  612.  
  613.   /* prepend the program name */
  614.   arg = (struct Argument *) syscall (SYS_malloc, sizeof (*arg));
  615.  
  616.   /* some stupid shells (like Wsh...) pass the WHOLE path of the
  617.    * started program. We simply cut off what we don't want ;-)) */
  618.   for (arglen = arg0[0]; arglen; --arglen)
  619.     if (arg0[arglen] == ':' || arg0[arglen] == '/') break;
  620.  
  621.   line = &arg0[arglen+1];
  622.   arglen = arg0[0] - arglen;
  623.  
  624.   arg->a_arg = (char *) syscall (SYS_malloc, arglen+1);
  625.  
  626.   strncpy (arg->a_arg, line, arglen);
  627.   arg->a_arg[arglen] = 0;
  628.   /* did I tell you, that I like those kernel list calls ?? */
  629.   AddHead ((struct List*) &ArgList, (struct Node*) arg);
  630.   ++ ArgList.al_num;
  631.  
  632.   /* build _argv array */
  633.   *argv = (char **) syscall (SYS_malloc, (ArgList.al_num+1) * sizeof(char *));
  634.   for (cpp = *argv, arg = (struct Argument *) ArgList.al_list.mlh_Head;
  635.        narg = (struct Argument *) arg->a_node.mln_Succ;
  636.        arg = narg)
  637.     *cpp++ = arg->a_arg;
  638.  
  639.   /* guarantee last element == 0 */        
  640.   *cpp = 0;
  641.   *argc = ArgList.al_num;
  642.  
  643.   syscall (SYS_sigsetmask, omask);
  644. }
  645. @
  646.  
  647.  
  648. 1.2
  649. log
  650. @make stderr (desc 2) *really* read/write, don't just say so...
  651. @
  652. text
  653. @d19 1
  654. a19 1
  655.  *  $Id: _cli_parse.c,v 1.1 1992/05/14 19:55:40 mwild Exp $
  656. d22 3
  657. a63 1
  658. #define Process Process_13
  659. a64 33
  660. #undef Process
  661.  
  662. struct Process {
  663.     struct  Task    pr_Task;
  664.     struct  MsgPort pr_MsgPort; /* This is BPTR address from DOS functions  */
  665.     WORD    pr_Pad;        /* Remaining variables on 4 byte boundaries */
  666.     BPTR    pr_SegList;        /* Array of seg lists used by this process  */
  667.     LONG    pr_StackSize;    /* Size of process stack in bytes        */
  668.     APTR    pr_GlobVec;        /* Global vector for this process (BCPL)    */
  669.     LONG    pr_TaskNum;        /* CLI task number of zero if not a CLI        */
  670.     BPTR    pr_StackBase;    /* Ptr to high memory end of process stack  */
  671.     LONG    pr_Result2;        /* Value of secondary result from last call */
  672.     BPTR    pr_CurrentDir;    /* Lock associated with current directory   */
  673.     BPTR    pr_CIS;        /* Current CLI Input Stream            */
  674.     BPTR    pr_COS;        /* Current CLI Output Stream            */
  675.     APTR    pr_ConsoleTask;    /* Console handler process for current window*/
  676.     APTR    pr_FileSystemTask;    /* File handler process for current drive   */
  677.     BPTR    pr_CLI;        /* pointer to CommandLineInterface        */
  678.     APTR    pr_ReturnAddr;    /* pointer to previous stack frame        */
  679.     APTR    pr_PktWait;        /* Function to be called when awaiting msg  */
  680.     APTR    pr_WindowPtr;    /* Window for error printing            */
  681.  
  682.     /* following definitions are new with 2.0 */
  683.     BPTR    pr_HomeDir;        /* Home directory of executing program        */
  684.     LONG    pr_Flags;        /* flags telling dos about process        */
  685.     void    (*pr_ExitCode)();    /* code to call on exit of program or NULL  */
  686.     LONG    pr_ExitData;    /* Passed as an argument to pr_ExitCode.    */
  687.     UBYTE   *pr_Arguments;    /* Arguments passed to the process at start */
  688.     struct MinList pr_LocalVars; /* Local environment variables            */
  689.     ULONG   pr_ShellPrivate;    /* for the use of the current shell        */
  690.     BPTR    pr_CES;        /* Error stream - if NULL, use pr_COS        */
  691. };  /* Process */
  692.  
  693. d72 1
  694. a73 11
  695. #define NO_PROTOTYPES
  696. /* we'll use inline headers, they would collide with these definitions.. */
  697. #include <libraries/arpbase.h>
  698. #undef NO_PROTOTYPES
  699. #include <packets.h>
  700. #include <string.h>
  701. #include <ctype.h>
  702.  
  703. #include <string.h>
  704. #include <stdlib.h>
  705. #include <unistd.h>
  706. d80 1
  707. a80 16
  708. #include <inline/arp.h>
  709.  
  710. #if __GNUC__ != 2
  711. #define alloca __builtin_alloca
  712. #endif
  713.  
  714. extern int _dos20;
  715.  
  716. /* CAN'T include inline20/dos.h, because this would collide with many
  717.  * definitions inside arpbase.h. Those functions are 99% identical to the
  718.  * ARP equivalents, they probably originated in ARP.. */
  719. #define BASE_EXT_DECL
  720. #define BASE_PAR_DECL    
  721. #define BASE_PAR_DECL0    
  722. #define BASE_NAME    ix.ix_dos_base
  723. __inline static LONG MatchFirst(BASE_PAR_DECL const UBYTE* pat, struct AnchorPath* anchor)
  724. d85 2
  725. a86 2
  726.     register const UBYTE* d1 __asm("d1");
  727.     register struct AnchorPath* d2 __asm("d2");
  728. d89 2
  729. a90 2
  730.     d1 = pat;
  731.     d2 = anchor;
  732. d92 4
  733. a95 4
  734.     jsr a6@@(-0x336)"
  735.     : "=g" (res)
  736.     : "g" (a6), "g" (d1), "g" (d2)
  737.     : "d0", "d1", "a0", "a1", "d2");
  738. a96 1
  739.     *(char *)d2=*(char *)d2;
  740. d98 1
  741. a98 1
  742. __inline static LONG MatchNext(BASE_PAR_DECL struct AnchorPath* anchor)
  743. d103 1
  744. a103 1
  745.     register struct AnchorPath* d1 __asm("d1");
  746. d106 1
  747. a106 1
  748.     d1 = anchor;
  749. d108 4
  750. a111 5
  751.     jsr a6@@(-0x33c)"
  752.     : "=g" (res)
  753.     : "g" (a6), "g" (d1)
  754.     : "d0", "d1", "a0", "a1");
  755.     *(char *)d1=*(char *)d1;
  756. d114 1
  757. a114 1
  758. __inline static void MatchEnd(BASE_PAR_DECL struct AnchorPath* anchor)
  759. d118 1
  760. a118 1
  761.     register struct AnchorPath* d1 __asm("d1");
  762. d121 1
  763. a121 1
  764.     d1 = anchor;
  765. d123 1
  766. a123 1
  767.     jsr a6@@(-0x342)"
  768. d125 2
  769. a126 3
  770.     : "g" (a6), "g" (d1)
  771.     : "d0", "d1", "a0", "a1");
  772.     *(char *)d1=*(char *)d1;
  773. d128 6
  774. a133 4
  775. #undef BASE_EXT_DECL
  776. #undef BASE_PAR_DECL
  777. #undef BASE_PAR_DECL0
  778. #undef BASE_NAME
  779. d358 1
  780. a358 1
  781.     ap = syscall (SYS_memalign, 4, sizeof(*ap));
  782. d361 2
  783. a362 2
  784.       ap = syscall (SYS_memalign, 4, sizeof(*ap)+MAXPATHLEN);
  785.       ap->ap_StrLen = MAXPATHLEN - 1;
  786. d367 1
  787. a367 1
  788.   ap->ap_Flags = APF_DoDot;
  789. @
  790.  
  791.  
  792. 1.1
  793. log
  794. @Initial revision
  795. @
  796. text
  797. @d19 1
  798. a19 1
  799.  *  $Id$
  800. d21 4
  801. a24 1
  802.  *  $Log$
  803. d375 1
  804. a375 1
  805.           fp->f_read  = 0;
  806. @
  807.