#line 1014 "/home/travis/build/felix-lang/felix/src/packages/program.fdoc"
  
  
  /* http://msdn.microsoft.com/en-us/library/17w5ykft.aspx
  Microsoft Specific
  
  Microsoft C/C++ startup code uses the following rules when interpreting
  arguments given on the operating system command line:
  
      Arguments are delimited by white space, which is either a space or a tab.
  
      The caret character (^) is not recognized as an escape character or delimiter.
      The character is handled completely by the command-line parser in the
      operating system before being passed to the argv array in the program.
  
      A string surrounded by double quotation marks ("string") is
      interpreted as a single argument, regardless of white space contained within.
      A quoted string can be embedded in an argument.
  
      A double quotation mark preceded by a backslash (\") is
      interpreted as a literal double quotation mark character (").
  
      Backslashes are interpreted literally, unless they
      immediately precede a double quotation mark.
  
      If an even number of backslashes is followed by a
      double quotation mark, one backslash is placed in the argv
      array for every pair of backslashes, and the double quotation mark
      is interpreted as a string delimiter.
  
      If an odd number of backslashes is followed by a
      double quotation mark, one backslash is placed in the argv
      array for every pair of backslashes, and the double quotation mark
      is "escaped" by the remaining backslash, causing a literal
      double quotation mark (") to be placed in argv.
  */
  
  class CmdExe
  {
    instance Shell_class[Win32, Win32Process::process_status_t]
    {
      fun quote_arg(s:string):string => '"' + s + '"';
      fun quote_line_for_system(s:string) => '"' + s + '"';
      fun quote_line_for_popen(s:string) => '"' + s + '"';
  
      gen raw_get_stdout(x:string) = {
        //eprintln("CMD.EXE: raw_get_stout of " + x);
        var fout = Win32Process::popen_in(x);
        if valid fout do
          var output = load fout;
          var result = Win32Process::pclose fout;
          return Win32Process::int_of_process_status_t result, output;
        else
          println$ "Unable to run command '" + x "'";
          return -1,"";
        done
      }
  
      Parse a CMD.EXE command line into words.
      fun parse (s:string) : list[string] =
      {
        var args = Empty[string];
        var current = "";
        union mode_t = | copy | skip | dquote | escape-copy | escape-dquote;
        var mode = skip;
        for ch in s do
          match mode with
          | #skip =>
            if ch == char "\\" do
              mode = escape-copy;
            elif ch == char '"' do
              mode = dquote;
            elif ord ch > ord (char ' ') do
              current += ch;
              mode = copy;
            done
  
          | #copy =>
            if ch == char "\\" do
              mode = escape-copy;
            elif ord ch <= ord (char ' ') do
              mode = skip;
              args += current;
              current = "";
            elif ch == char '"' do
              mode = dquote;
            else
              current += ch;
            done
  
          | #escape-copy =>
            mode = copy;
            if ch == char '"' do
              current += ch;
            else
              current += "\\" + ch;
            done
  
          | #escape-dquote =>
            mode = dquote;
            if ch == char '"' do
              current += ch;
            else
              current += "\\" + ch;
            done
  
          | #dquote =>
            if ch == char '"' do
              mode = copy;
            elif ch == char "\\" do
              mode = escape-dquote;
            else
              current += ch;
            done
          endmatch;
        done
        match mode with
        | #skip => ;
        | _ => args += current;
        endmatch;
        return args;
      }
    }
    inherit Shell_class[Win32, Win32Process::process_status_t];
  
  }