Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. #include<menuet/os.h>
  2. #include<unistd.h>
  3.  
  4. void _exit(int code)
  5. {
  6.  __asm__ __volatile__("int $0x40"::"a"(-1));
  7.  for(;;);
  8. }
  9.  
  10. #include <libc/stubs.h>
  11. #include <io.h>
  12. #include <unistd.h>
  13. #include <stdlib.h>
  14. #include <crt0.h>
  15. #include <libc/farptrgs.h>
  16. #include <ctype.h>
  17. #include <string.h>
  18. #include <fcntl.h>
  19.  
  20. #define ds _my_ds()
  21.  
  22.  
  23. extern char __menuet__app_param_area[];
  24. extern char __menuet__app_path_area[];
  25.  
  26. static void * c1xmalloc(size_t s)
  27. {
  28.  void *q = malloc(s);
  29.  if (q == 0)
  30.  {
  31. #define err(x)
  32.   err("No memory to gather arguments\r\n");
  33.   _exit(1);
  34.  }
  35.  return q;
  36. }
  37.  
  38. static int atohex(char *s)
  39. {
  40.   int rv = 0;
  41.   while (*s)
  42.   {
  43.     int v = *s - '0';
  44.     if (v > 9)
  45.       v -= 7;
  46.     v &= 15; /* in case it's lower case */
  47.     rv = rv*16 + v;
  48.     s++;
  49.   }
  50.   return rv;
  51. }
  52.  
  53. typedef struct Arg {
  54.   char *arg;
  55.   char **arg_globbed;
  56.   struct ArgList *arg_file;
  57.   struct Arg *next;
  58.   int was_quoted;
  59. } Arg;
  60.  
  61. typedef struct ArgList {
  62.   int argc;
  63.   Arg **argv;
  64. } ArgList;
  65.  
  66. static Arg *new_arg(void)
  67. {
  68.   Arg *a = (Arg *)c1xmalloc(sizeof(Arg));
  69.   memset(a, 0, sizeof(Arg));
  70.   return a;
  71. }
  72.  
  73. static void delete_arglist(ArgList *al);
  74.  
  75. static void delete_arg(Arg *a)
  76. {
  77.   if (a->arg) free(a->arg);
  78.   if (a->arg_globbed)
  79.   {
  80.     int i;
  81.     for (i=0; a->arg_globbed[i]; i++)
  82.       free(a->arg_globbed[i]);
  83.     free(a->arg_globbed);
  84.   }
  85.   if (a->arg_file)
  86.     delete_arglist(a->arg_file);
  87.   free(a);
  88. }
  89.  
  90. static ArgList * new_arglist(int count)
  91. {
  92.   ArgList *al = (ArgList *)c1xmalloc(sizeof(ArgList));
  93.   al->argc = count;
  94.   al->argv = (Arg **)c1xmalloc((count+1)*sizeof(Arg *));
  95.   memset(al->argv, 0, (count+1)*sizeof(Arg *));
  96.   return al;
  97. }
  98.  
  99. static void delete_arglist(ArgList *al)
  100. {
  101.   int i;
  102.   for (i=0; i<al->argc; i++)
  103.     delete_arg(al->argv[i]);
  104.   free(al->argv);
  105.   free(al);
  106. }
  107.  
  108. static char * parse_arg(char *bp, char *last, int unquote, size_t *len, int *was_quoted)
  109. {
  110.   char *ep = bp, *epp = bp;
  111.   int quote=0;
  112.  
  113.   while ((quote || !isspace(*(unsigned char *)ep)) && ep < last)
  114.   {
  115.     if (quote && *ep == quote)
  116.     {
  117.       quote = 0;
  118.       if (!unquote)
  119.         *epp++ = *ep;
  120.       ep++;
  121.     }
  122.     else if (!quote && (*ep == '\'' || *ep == '"'))
  123.     {
  124.       quote = *ep++;
  125.       if (!unquote)
  126.         *epp++ = quote;
  127.     }
  128.     else if (*ep == '\\' && strchr("'\"", ep[1]) && ep < last-1)
  129.     {
  130.       if (!unquote)
  131.         *epp++ = *ep;
  132.       ep++;
  133.       *epp++ = *ep++;
  134.       /* *was_quoted = 1;  - This makes no sense. */
  135.     }
  136.     else
  137.     {
  138.       if ((quote && (strchr("[?*", *ep) || strncmp(ep, "...", 3) == 0))
  139.           && unquote)
  140.         *was_quoted = 1;
  141.       *epp++ = *ep++;
  142.     }
  143.   }
  144.  
  145.   *len = epp - bp;
  146.   return ep;
  147. }
  148.  
  149. static ArgList * parse_bytes(char *bytes, int length, int unquote)
  150. {
  151.   int largc, i;
  152.   Arg *a, **anext, *afirst;
  153.   ArgList *al;
  154.   char *bp=bytes, *ep, *last=bytes+length;
  155.  
  156.   anext = &afirst;
  157.   largc = 0;
  158.   while (bp<last)
  159.   {
  160.     size_t arg_len;
  161.     while (isspace(*(unsigned char *)bp) && bp < last)
  162.       bp++;
  163.     if (bp == last)
  164.       break;
  165.     *anext = a = new_arg();
  166.     ep = parse_arg(bp, last, unquote, &arg_len, &(a->was_quoted));
  167.     anext = &(a->next);
  168.     largc++;
  169.     a->arg = (char *)c1xmalloc(arg_len+1);
  170.     memcpy(a->arg, bp, arg_len);
  171.     a->arg[arg_len] = 0;
  172.     bp = ep+1;
  173.   }
  174.   al = new_arglist(largc);
  175.   for (i=0, a=afirst; i<largc; i++, a=a->next)
  176.     al->argv[i] = a;
  177.   return al;
  178. }
  179.  
  180. static ArgList * parse_print0(char *bytes, int length)
  181. {
  182.   int largc, i;
  183.   Arg *a, **anext, *afirst;
  184.   ArgList *al;
  185.   char *bp=bytes, *ep, *last=bytes+length;
  186.  
  187.   anext = &afirst;
  188.   largc = 0;
  189.   while (bp<last)
  190.   {
  191.     size_t arg_len = strlen(bp);
  192.     ep = bp;
  193.     bp += arg_len + 1;
  194.     *anext = a = new_arg();
  195.     a->was_quoted = 1;
  196.     anext = &(a->next);
  197.     largc++;
  198.     a->arg = (char *)c1xmalloc(arg_len+1);
  199.     memcpy(a->arg, ep, arg_len);
  200.     a->arg[arg_len] = 0;
  201.   }
  202.   al = new_arglist(largc);
  203.   for (i=0, a=afirst; i<largc; i++, a=a->next)
  204.     al->argv[i] = a;
  205.   return al;
  206. }
  207.  
  208. static int count_args(ArgList *al)
  209. {
  210.   int i, r=0;
  211.   for (i=0; i<al->argc; i++)
  212.   {
  213.     int j;
  214.     if (al->argv[i]->arg_globbed)
  215.     {
  216.       for (j=0; al->argv[i]->arg_globbed[j]; j++);
  217.       r += j;
  218.     }
  219.     else if (al->argv[i]->arg_file)
  220.     {
  221.       r += count_args(al->argv[i]->arg_file);
  222.     }
  223.     else
  224.     {
  225.       r++;
  226.     }
  227.   }
  228.   return r;
  229. }
  230.  
  231. static char ** fill_args(char **largv, ArgList *al)
  232. {
  233.   int i;
  234.   for (i=0; i<al->argc; i++)
  235.   {
  236.     int j;
  237.     if (al->argv[i]->arg_globbed)
  238.     {
  239.       for (j=0; al->argv[i]->arg_globbed[j]; j++)
  240.       {
  241.         *largv++ = al->argv[i]->arg_globbed[j];
  242.         al->argv[i]->arg_globbed[j] = 0;
  243.       }
  244.     }
  245.     else if (al->argv[i]->arg_file)
  246.     {
  247.       largv = fill_args(largv, al->argv[i]->arg_file);
  248.     }
  249.     else
  250.     {
  251.       *largv++ = al->argv[i]->arg;
  252.       al->argv[i]->arg = 0;
  253.     }
  254.   }
  255.   return largv;
  256. }
  257.  
  258. static void expand_response_files(ArgList *al)
  259. {
  260.   int i, f;
  261.   for (i=0; i<al->argc; i++)
  262.   {
  263.     if (! al->argv[i]->was_quoted && al->argv[i]->arg[0] == '@')
  264.       if ((f = _open(al->argv[i]->arg+1, O_RDONLY)) >= 0)
  265.       {
  266.         char *bytes;
  267.         int len, st_size;
  268.         st_size = lseek(f, 0L, SEEK_END);
  269.         lseek(f, 0L, SEEK_SET);
  270.         if (st_size < 0)
  271.           st_size = 0;
  272.         bytes = (char *)c1xmalloc(st_size+1);
  273.         len = _read(f, bytes, st_size);
  274.         if (len < 0)
  275.           len = 0;
  276.         _close(f);
  277.         /* if the last character is ^Z, remove it */
  278.         if (len > 0 && bytes[len-1] == 0x1a)
  279.           len--;
  280.         /* assume 'find -print0' if the last char is a '\0' */
  281.         if (len > 0 && bytes[len-1] == '\0')
  282.           al->argv[i]->arg_file = parse_print0(bytes, len);
  283.         else
  284.           al->argv[i]->arg_file = parse_bytes(bytes, len, (_crt0_startup_flags & _CRT0_FLAG_KEEP_QUOTES) == 0);
  285.         expand_response_files(al->argv[i]->arg_file);
  286.         free(bytes);
  287.       }
  288.   }
  289. }
  290.  
  291. static void expand_wildcards(ArgList *al)
  292. {
  293.   int i;
  294.   for (i=0; i<al->argc; i++)
  295.   {
  296.     if (al->argv[i]->arg_file)
  297.       expand_wildcards(al->argv[i]->arg_file);
  298.     else if (!(al->argv[i]->was_quoted))
  299.     {
  300.       al->argv[i]->arg_globbed = __crt0_glob_function(al->argv[i]->arg);
  301.     }
  302.   }
  303. }
  304.  
  305. static void add_arg(const char* arg, const char* end)
  306. {
  307.         char* res;
  308.         __crt0_argv = realloc(__crt0_argv, 4*(++__crt0_argc));
  309.         res = malloc(end-arg+1);
  310.         if (!__crt0_argv || !res) _exit(1);
  311.         __crt0_argv[__crt0_argc-1] = res;
  312.         while (arg < end)
  313.         {
  314.                 if (arg[0] == '"' && arg[1] == '"') ++arg;
  315.                 *res++ = *arg++;
  316.         }
  317.         *res = 0;
  318. }
  319.  
  320. void __crt0_setup_arguments(void)
  321. {
  322. #if 0
  323. // ­¥ ¡ã¤¥¬ áâà ¤ âì 䨣­ñ©...
  324.   ArgList *arglist;
  325.   char *argv0;
  326.   int prepend_argv0 = 1;
  327.   int should_expand_wildcards = 1;
  328.   char *proxy_v = 0;
  329.   argv0="menuet.app";
  330.   /*
  331.   ** Next, scan dos's command line.
  332.   */
  333.   {
  334.     char doscmd[128];
  335.     memcpy(doscmd+1,__menuet__app_param_area,128);
  336.     arglist = parse_bytes(doscmd+1, doscmd[0] & 0x7f,
  337.                           (_crt0_startup_flags & _CRT0_FLAG_KEEP_QUOTES) == 0);
  338.   }
  339.  
  340.   /*
  341.   **  Now, expand response files
  342.   */
  343.   if (!(_crt0_startup_flags & _CRT0_FLAG_DISALLOW_RESPONSE_FILES))
  344.     expand_response_files(arglist);
  345.  
  346.   /*
  347.   **  Now, expand wildcards
  348.   */
  349.  
  350.   if (should_expand_wildcards)
  351.     expand_wildcards(arglist);
  352.  
  353.   __crt0_argc = prepend_argv0 + count_args(arglist);
  354.   __crt0_argv = (char **)c1xmalloc((__crt0_argc+1) * sizeof(char *));
  355.   if (prepend_argv0)
  356.     __crt0_argv[0] = argv0;
  357.   *fill_args(__crt0_argv+prepend_argv0, arglist) = 0;
  358. #else
  359. // ...  ¯à®áâ® à §¡¥àñ¬ ª®¬ ­¤­ãî áâபã. - diamond
  360.         char* ptr;
  361.         char* cur_arg=NULL;
  362.         int bInQuote=0;
  363.         add_arg(__menuet__app_path_area,
  364.                 __menuet__app_path_area + strlen(__menuet__app_path_area));
  365.         for (ptr=__menuet__app_param_area;*ptr && ptr<__menuet__app_param_area+256;ptr++)
  366.         {
  367.                 if (*ptr == ' ' || *ptr == '\t')
  368.                 {
  369.                         if (cur_arg && !bInQuote)
  370.                         {
  371.                                 add_arg(cur_arg,ptr);
  372.                                 cur_arg = NULL;
  373.                         }
  374.                         continue;
  375.                 }
  376.                 if (*ptr == '"')
  377.                 {
  378.                         if (ptr[1] == '"')
  379.                         {if (!cur_arg) cur_arg=ptr;ptr++;}
  380.                         else
  381.                         {
  382.                                 if (cur_arg)
  383.                                 {
  384.                                         add_arg(cur_arg,ptr);
  385.                                         if (bInQuote)
  386.                                         {
  387.                                                 bInQuote = 0;
  388.                                                 cur_arg = NULL;
  389.                                                 continue;
  390.                                         }
  391.                                 }
  392.                                 bInQuote = 1;
  393.                                 cur_arg = ptr+1;
  394.                         }
  395.                         continue;
  396.                 }
  397.                 if (!cur_arg) cur_arg = ptr;
  398.         }
  399.         if (cur_arg) add_arg(cur_arg,ptr);
  400. #endif
  401. }
  402.