parse_arguments Subroutine

public subroutine parse_arguments(filename, show_help, verbose_level, custom_cache_dir, custom_config_dir, parallel_jobs, no_wait, notebook_mode, notebook_output, standardize_only, custom_flags, clear_cache, cache_info, debug_tokens, debug_ast, debug_semantic, debug_standardize, debug_codegen, from_tokens, from_ast, from_semantic, show_version)

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(out) :: filename
logical, intent(out) :: show_help
integer, intent(out) :: verbose_level
character(len=*), intent(out) :: custom_cache_dir
character(len=*), intent(out) :: custom_config_dir
integer, intent(out) :: parallel_jobs
logical, intent(out) :: no_wait
logical, intent(out) :: notebook_mode
character(len=*), intent(out) :: notebook_output
logical, intent(out) :: standardize_only
character(len=*), intent(out), optional :: custom_flags
logical, intent(out) :: clear_cache
logical, intent(out) :: cache_info
logical, intent(out) :: debug_tokens
logical, intent(out) :: debug_ast
logical, intent(out) :: debug_semantic
logical, intent(out) :: debug_standardize
logical, intent(out) :: debug_codegen
logical, intent(out) :: from_tokens
logical, intent(out) :: from_ast
logical, intent(out) :: from_semantic
logical, intent(out), optional :: show_version

Source Code

    subroutine parse_arguments(filename, show_help, verbose_level, custom_cache_dir, &
                             custom_config_dir, parallel_jobs, no_wait, notebook_mode, &
                               notebook_output, standardize_only, custom_flags, &
      clear_cache, cache_info, debug_tokens, debug_ast, debug_semantic, debug_standardize, debug_codegen, &
                               from_tokens, from_ast, from_semantic, show_version)
        character(len=*), intent(out) :: filename
        logical, intent(out) :: show_help
        integer, intent(out) :: verbose_level
        character(len=*), intent(out) :: custom_cache_dir
        character(len=*), intent(out) :: custom_config_dir
        integer, intent(out) :: parallel_jobs
        logical, intent(out) :: no_wait
        logical, intent(out) :: notebook_mode
        character(len=*), intent(out) :: notebook_output
        logical, intent(out) :: standardize_only
        character(len=*), intent(out), optional :: custom_flags
        logical, intent(out) :: clear_cache
        logical, intent(out) :: cache_info
        logical, intent(out) :: debug_tokens
        logical, intent(out) :: debug_ast
        logical, intent(out) :: debug_semantic
        logical, intent(out) :: debug_standardize
        logical, intent(out) :: debug_codegen
        logical, intent(out) :: from_tokens
        logical, intent(out) :: from_ast
        logical, intent(out) :: from_semantic
        logical, intent(out), optional :: show_version

        integer :: nargs, i, iostat
        character(len=256) :: arg
        logical :: filename_found, expecting_cache_dir, expecting_config_dir, expecting_jobs, expecting_output, expecting_flags

        filename = ''
        show_help = .false.
        verbose_level = 0
        custom_cache_dir = ''
        custom_config_dir = ''
        parallel_jobs = 0  ! 0 means use FPM default
        no_wait = .false.
        notebook_mode = .false.
        notebook_output = ''
        standardize_only = .false.
        clear_cache = .false.
        cache_info = .false.
        debug_tokens = .false.
        debug_ast = .false.
        debug_semantic = .false.
        debug_standardize = .false.
        debug_codegen = .false.
        from_tokens = .false.
        from_ast = .false.
        from_semantic = .false.
        if (present(custom_flags)) then
            custom_flags = ''
        end if
        if (present(show_version)) then
            show_version = .false.
        end if
        filename_found = .false.
        expecting_cache_dir = .false.
        expecting_config_dir = .false.
        expecting_jobs = .false.
        expecting_output = .false.
        expecting_flags = .false.

        nargs = command_argument_count()

        if (nargs == 0) then
            ! When no arguments provided, show help
            show_help = .true.
            return
        end if

        i = 1
        do while (i <= nargs)
            call get_command_argument(i, arg)

            if (expecting_cache_dir) then
                custom_cache_dir = trim(arg)
                expecting_cache_dir = .false.
            else if (expecting_config_dir) then
                custom_config_dir = trim(arg)
                expecting_config_dir = .false.
            else if (expecting_output) then
                if (notebook_mode) then
                    notebook_output = trim(arg)
                else
                    notebook_output = trim(arg)  ! fallback
                end if
                expecting_output = .false.
            else if (expecting_flags) then
                if (present(custom_flags)) then
                    custom_flags = trim(arg)
                end if
                expecting_flags = .false.
            else if (expecting_jobs) then
                read (arg, *, iostat=iostat) parallel_jobs
                if (iostat /= 0 .or. parallel_jobs < 1) then
               print '(a)', 'Error: Invalid number of jobs. Must be a positive integer.'
                    stop 1
                end if
                expecting_jobs = .false.
            else if (arg == '--help' .or. arg == '-h') then
                show_help = .true.
                return
            else if (arg == '--version') then
                if (present(show_version)) then
                    show_version = .true.
                    return
                end if
            else if (arg == '-v') then
                verbose_level = 1
            else if (arg == '-vv') then
                verbose_level = 2
            else if (arg == '-vvv') then
                verbose_level = 3
            else if (arg == '--verbose') then
                ! Check if next argument is a number (1 or 2)
                if (i < nargs) then
                    call get_command_argument(i + 1, arg)
                    if (arg == '1') then
                        verbose_level = 1
                        i = i + 1  ! Skip the next argument since we consumed it
                    else if (arg == '2') then
                        verbose_level = 2
                        i = i + 1  ! Skip the next argument since we consumed it
                    else if (arg == '3') then
                        verbose_level = 3
                        i = i + 1  ! Skip the next argument since we consumed it
                    else
                        ! Next arg is not a number, default to level 1
                        verbose_level = 1
                    end if
                else
                    ! No more arguments, default to level 1
                    verbose_level = 1
                end if
            else if (arg == '--cache-dir') then
                expecting_cache_dir = .true.
            else if (arg == '--config-dir') then
                expecting_config_dir = .true.
            else if (arg == '-j' .or. arg == '--jobs') then
                expecting_jobs = .true.
            else if (arg == '--no-wait') then
                no_wait = .true.
            else if (arg == '--notebook') then
                notebook_mode = .true.
            else if (arg == '--standardize') then
                standardize_only = .true.
            else if (arg == '--emit-f90') then
                ! --emit-f90 is a synonym for --standardize
                standardize_only = .true.
            else if (arg == '--clear-cache') then
                clear_cache = .true.
            else if (arg == '--cache-info') then
                cache_info = .true.
            else if (arg == '--debug-tokens') then
                debug_tokens = .true.
            else if (arg == '--debug-ast') then
                debug_ast = .true.
            else if (arg == '--debug-semantic') then
                debug_semantic = .true.
            else if (arg == '--debug-standardize') then
                debug_standardize = .true.
            else if (arg == '--debug-codegen') then
                debug_codegen = .true.
            else if (arg == '--from-tokens') then
                from_tokens = .true.
            else if (arg == '--from-ast') then
                from_ast = .true.
            else if (arg == '--from-semantic') then
                from_semantic = .true.
                ! MLIR compilation modes moved to fortc package
            else if (arg == '-o' .or. arg == '--output') then
                expecting_output = .true.
            else if (arg == '--flag') then
                if (present(custom_flags)) then
                    expecting_flags = .true.
                else
                    ! Flag option used but custom_flags not provided - skip silently
                    if (i < nargs) i = i + 1  ! Skip the next argument
                end if
            else if (arg(1:1) /= '-') then
                ! Not a flag, must be filename
                if (.not. filename_found) then
                    ! Assign to module variable first
                    module_filename = arg(1:len_trim(arg))
                    ! Then copy to output parameter
                    filename = module_filename(1:len_trim(module_filename))
                    filename_found = .true.
                end if
            end if

            i = i + 1
        end do

        if (expecting_cache_dir) then
            print '(a)', 'Error: --cache-dir requires an argument'
            show_help = .true.
        end if

        if (expecting_config_dir) then
            print '(a)', 'Error: --config-dir requires an argument'
            show_help = .true.
        end if

        if (expecting_jobs) then
            print '(a)', 'Error: -j/--jobs requires a number'
            show_help = .true.
        end if

        if (expecting_output) then
            print '(a)', 'Error: -o/--output requires an argument'
            show_help = .true.
        end if

        if (expecting_flags) then
            print '(a)', 'Error: --flag requires an argument'
            show_help = .true.
        end if

        ! Cache management commands don't require a filename
        if (.not. filename_found .and. .not. clear_cache .and. .not. cache_info) then
            show_help = .true.
        end if

        ! If notebook mode and no output specified, generate default
        if (notebook_mode .and. notebook_output == '') then
            call generate_default_output_name(filename, notebook_output)
        end if

    end subroutine parse_arguments