Parse the complete CLI and produce watcher options + typed fpm settings.
Parsing order:
1. Initialize watcher options from defaults and fpm.toml.
2. Consume leading --watch-* options and verbosity flags (-q, -v).
3. Identify the fpm subcommand (build|test|run).
4. Parse selected fpm settings used to build the model (profile, flags,
compilers, build-dir, features, and run/test names).
All arguments after the subcommand are also preserved in fpm_cmdline.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(watch_opts_t), | intent(out) | :: | w | |||
| class(fpm_build_settings), | intent(out), | allocatable | :: | settings | ||
| character(len=:), | intent(out), | allocatable | :: | fpm_cmdline | ||
| character(len=:), | intent(out), | allocatable | :: | subcmd |
subroutine parse_cli(w, settings, fpm_cmdline, subcmd) type(watch_opts_t), intent(out) :: w class(fpm_build_settings), allocatable, intent(out) :: settings character(len=:), allocatable, intent(out) :: fpm_cmdline character(len=:), allocatable, intent(out) :: subcmd integer :: narg, i, subcmd_pos character(len=:), allocatable :: a character(len=:), allocatable :: profile, build_dir character(len=:), allocatable :: compiler, c_compiler, cxx_compiler, archiver character(len=:), allocatable :: flag, cflag, cxxflag, ldflag character(len=:), allocatable :: runner type(string_t), allocatable :: features(:) type(string_t), allocatable :: names(:) logical :: prune, example call set_watch_defaults(w) call apply_watch_from_manifest(w) prune = .true. example = .false. profile = "" build_dir = default_build_dir() compiler = "" c_compiler = "" cxx_compiler = "" archiver = "" flag = "" cflag = "" cxxflag = "" ldflag = "" runner = "" allocate(features(0)) allocate(names(0)) narg = command_argument_count() if (narg < 1) then call usage_and_stop("missing fpm subcommand (build/test/run)") end if a = get_arg(1) if (a == "--help" .or. a == "-h") then call usage_and_stop_ok() end if i = 1 do while (i <= narg) a = get_arg(i) if (is_watch_flag(a)) then call apply_watch_flag(a, i, narg, w) i = i + 1 cycle end if if (a == "-q") then w%verbosity = -1 i = i + 1 cycle end if if (a == "-v") then w%verbosity = max(w%verbosity, 1) i = i + 1 cycle end if if (a == "-vv") then w%verbosity = max(w%verbosity, 2) i = i + 1 cycle end if exit end do if (i > narg) call usage_and_stop("missing fpm subcommand (build/test/run)") a = get_arg(i) if (a == "--help" .or. a == "-h") then call usage_and_stop_ok() end if subcmd_pos = i subcmd = get_arg(subcmd_pos) if (.not. is_supported_subcmd(subcmd)) then call usage_and_stop("unsupported subcommand: " // trim(subcmd) // " (supported: build,test,run)") end if if (subcmd_pos < narg) then fpm_cmdline = "fpm " // trim(subcmd) // " " // join_argv(subcmd_pos+1, narg) else fpm_cmdline = "fpm " // trim(subcmd) end if i = subcmd_pos + 1 do while (i <= narg) a = get_arg(i) if (a == "--") exit select case (a) case ("--profile") if (i+1 > narg) call usage_and_stop("--profile requires a value") profile = get_arg(i+1) i = i + 2 cycle case ("--features") if (i+1 > narg) call usage_and_stop("--features requires a value") call add_features_csv(features, get_arg(i+1)) i = i + 2 cycle case ("--build-dir") if (i+1 > narg) call usage_and_stop("--build-dir requires a value") build_dir = get_arg(i+1) i = i + 2 cycle case ("--compiler") if (i+1 > narg) call usage_and_stop("--compiler requires a value") compiler = get_arg(i+1) i = i + 2 cycle case ("--c-compiler") if (i+1 > narg) call usage_and_stop("--c-compiler requires a value") c_compiler = get_arg(i+1) i = i + 2 cycle case ("--cxx-compiler") if (i+1 > narg) call usage_and_stop("--cxx-compiler requires a value") cxx_compiler = get_arg(i+1) i = i + 2 cycle case ("--archiver") if (i+1 > narg) call usage_and_stop("--archiver requires a value") archiver = get_arg(i+1) i = i + 2 cycle case ("--flag") if (i+1 > narg) call usage_and_stop("--flag requires a value") flag = get_arg(i+1) i = i + 2 cycle case ("--c-flag") if (i+1 > narg) call usage_and_stop("--c-flag requires a value") cflag = get_arg(i+1) i = i + 2 cycle case ("--cxx-flag") if (i+1 > narg) call usage_and_stop("--cxx-flag requires a value") cxxflag = get_arg(i+1) i = i + 2 cycle case ("--link-flag") if (i+1 > narg) call usage_and_stop("--link-flag requires a value") ldflag = get_arg(i+1) i = i + 2 cycle case ("--runner") if (i+1 > narg) call usage_and_stop("--runner requires a value") runner = get_arg(i+1) i = i + 2 cycle case ("--prune") prune = .true. i = i + 1 cycle case ("--no-prune") prune = .false. i = i + 1 cycle case ("--example") example = .true. i = i + 1 cycle case default if (trim(subcmd) == "run" .or. trim(subcmd) == "test") then if (len_trim(a) > 0) then if (a(1:1) /= "-") call push_feature(names, a) end if end if i = i + 1 cycle end select end do select case (trim(subcmd)) case ("build") allocate(fpm_build_settings :: settings) call init_build_settings(settings, build_dir, prune, profile, features, compiler, c_compiler, cxx_compiler, archiver, flag, cflag, cxxflag, ldflag) case ("test") allocate(fpm_test_settings :: settings) call init_build_settings(settings, build_dir, prune, profile, features, compiler, c_compiler, cxx_compiler, archiver, flag, cflag, cxxflag, ldflag) select type (s => settings) type is (fpm_test_settings) s%build_tests = .true. if (len_trim(runner) > 0) s%runner = trim(runner) call set_names(s, names) end select case ("run") allocate(fpm_run_settings :: settings) call init_build_settings(settings, build_dir, prune, profile, features, compiler, c_compiler, cxx_compiler, archiver, flag, cflag, cxxflag, ldflag) select type (s => settings) type is (fpm_run_settings) s%example = example if (len_trim(runner) > 0) s%runner = trim(runner) call set_names(s, names) end select case default call usage_and_stop("unsupported subcommand: " // trim(subcmd) // " (supported: build,test,run)") end select call normalize_watch_opts(w) end subroutine parse_cli