#line 2980 "/home/travis/build/felix-lang/felix/src/packages/flx.fdoc"
  include "std/felix/config";
  
  include "std/felix/flx_cache";
  include "std/felix/flx_pkg";
  include "std/felix/flx_flxg";
  include "std/felix/flx_cxx";
  
  include "std/felix/flx/flx_control";
  include "std/felix/flx/flx_cmdopt";
  include "std/felix/flx/flx_depvars";
  include "std/felix/flx/flx_run";
  include "std/felix/toolchain_clang_config";
  include "std/felix/toolchain_interface";
  
  
  include "std/felix/toolchain/clang_osx";
  include "std/felix/toolchain/clang_iphoneos";
  include "std/felix/toolchain/clang_linux";
  include "std/felix/toolchain/gcc_osx";
  include "std/felix/toolchain/gcc_linux";
  include "std/felix/toolchain/msvc_win32";
  
  
  open FlxCache;
  
  // Felix version of THIS program (NOT the one being installed
  // if you're using flx to install Felix)
  
  
  class BootFlx
  {
    gen flx_processing
    (
      config:&Config::config_type,
      control:&FlxControl::control_type,
      loopctl:&FlxControl::loopctl_type,
      args:list[string]
    ) : int =
    {
      var result = 0;
      fun / (a:string, b:string) => Filename::join (a,b);
      FlxCmdOpt::processing_stage1 (config,control,loopctl,varray[string] args);
      if control*.VALIDATE_CACHE == 1 do
        check_cache(config, control);
      done
  
      if loopctl*.base == "" and control*.INREGEX == "" do
        if control*.CLEAR_CACHE != 1 do
          println "usage: flx [options] filename";
          System::exit(1);
        done
        System::exit(0);
      done
  
  
      var dbdir = config*.FLX_TARGET_DIR / "config";
      var pkgconfig = FlxPkgConfig::FlxPkgConfigQuery$ list[string] dbdir;
      var toolchain_name =
        if control*.FLX_TOOLCHAIN == "" then pkgconfig.getpkgfield1 ("toolchain", "toolchain")
        else control*.FLX_TOOLCHAIN
      ;
  
      var toolchain =
         match toolchain_name with
  
         | "toolchain_clang_osx" => toolchain_clang_osx
         | "toolchain_clang_iphoneos" => toolchain_clang_iphoneos
         | "toolchain_clang_linux" => toolchain_clang_linux
         | "toolchain_gcc_osx" => toolchain_gcc_osx
         | "toolchain_gcc_linux" => toolchain_gcc_linux
         | "toolchain_msvc_win32" => toolchain_msvc_win32
         | x =>
           Dynlink::load-plugin-func1 [toolchain_t,clang_config_t] ( dll-name=x, setup-str="")
         endmatch
      ;
      if control*.INREGEX != "" do
  
        begin
          control.USER_ARGS <- Shell::quote_arg(loopctl*.progname) + ' ' + control*.USER_ARGS;
          if control*.INDIR == "" do control.INDIR <- "."; done
          var regex = RE2 control*.INREGEX;
          if not regex.ok do
            eprintln$ "Malformed regex " + control*.INREGEX;
            result = 1;
            goto endoff;
          done
          var files = FileSystem::regfilesin (control*.INDIR, regex);
          var n = files.len.int;
          println$ "Processing " + files.len.str + " files";
          var i = 1;
          for file in files do
            var arg = Filename::join (control*.INDIR, file);
            loopctl*.path,loopctl*.ext = Filename::split_extension(arg);
            loopctl*.dir,loopctl*.base = Filename::split1(loopctl*.path);
            // temporary hack, to force reset of the linker filename, stdout, and expect
            // file names in cal_depvars so they depend on the current file.
            control.LINKER_OUTPUT_FILENAME <- "";
            control.STDOUT <- "";
            control.EXPECT <- "";
            var dvars = FlxDepvars::cal_depvars(toolchain,*config,control,*loopctl);
            println$ f"Processing [%02d/%02d]: %S" (i, n, file);
            var pe = processing_env(toolchain,*config,*control,dvars);
            result = pe.runit();
            if result != 0 goto endoff;
            ++i;
          done
        end
      else
        begin
          if control*.SHOWCODE == 1 do
              var prg =
                (if dvars.use_ext == "" then "// No file "+dvars.filebase+".(flx|fdoc) found"
                else load(dvars.filebase+"."+dvars.use_ext)
              );
              print prg;
          done
          var dvars = FlxDepvars::cal_depvars(toolchain,*config,control, *loopctl);
          var pe = processing_env(toolchain,*config,*control,dvars);
          result = pe.runit();
        end
      done
  endoff:>
      return result;
    }
  
    gen runflx(args:list[string]) : int =
    {
      var config = #Config::std_config;
      var control = #FlxControl::dflt_control;
      var loopctl = #FlxControl::init_loopctl;
      return flx_processing(&config, &control, &loopctl, args);
    }
  }