Skip to content

Commit

Permalink
Merge pull request #723 from bmad-sim/devel/85
Browse files Browse the repository at this point in the history
Cleanup of Tao command line parsing.
  • Loading branch information
DavidSagan authored Jan 10, 2024
2 parents 1875647 + 7883d73 commit d725dbd
Show file tree
Hide file tree
Showing 8 changed files with 224 additions and 201 deletions.
30 changes: 17 additions & 13 deletions sim_utils/string/word_read.f90
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
! out_str = "b"
! Note: If there is no matching end bracket then all characters after the opening bracket will be considered
! interior characters. For example, with "(abc]def", all characters after the "(" are interior characters.
! Note: brackets inside quotes are ignored.
!
! Input:
! in_str -- character(*): String to be parsed.
Expand Down Expand Up @@ -98,8 +99,8 @@ subroutine word_read (in_str, delim_list, word, ix_word, delim, delim_found, out
ix_b1 = 0
ix_b2 = 0
ix_b3 = 0
out_of_q1 = .true.
out_of_q2 = .true.
out_of_q1 = .true. ! Not in single quotes.
out_of_q2 = .true. ! Not in double quotes
exterior = .true.

! loop over all characters
Expand Down Expand Up @@ -151,19 +152,22 @@ subroutine word_read (in_str, delim_list, word, ix_word, delim, delim_found, out
! Ignore interior?

if (logic_option(.false., ignore_interior)) then
select case (ch)
case ('('); ix_b1 = ix_b1 + 1
case (')'); ix_b1 = ix_b1 - 1
case ('['); ix_b2 = ix_b2 + 1
case (']'); ix_b2 = ix_b2 - 1
case ('{'); ix_b3 = ix_b3 + 1
case ('}'); ix_b3 = ix_b3 - 1
case ("'"); out_of_q1 = .not. out_of_q1
case ('"'); out_of_q2 = .not. out_of_q2
end select
if (out_of_q1 .and. ch == '"') out_of_q2 = .not. out_of_q2
if (out_of_q2 .and. ch == "'") out_of_q1 = .not. out_of_q1

if (out_of_q1 .and. out_of_q2) then
select case (ch)
case ('('); ix_b1 = ix_b1 + 1
case (')'); ix_b1 = ix_b1 - 1
case ('['); ix_b2 = ix_b2 + 1
case (']'); ix_b2 = ix_b2 - 1
case ('{'); ix_b3 = ix_b3 + 1
case ('}'); ix_b3 = ix_b3 - 1
end select
endif

exterior = (ix_b1 == 0 .and. ix_b2 == 0 .and. ix_b3 == 0 .and. out_of_q1 .and. out_of_q2)
endif

enddo

! here if no delim found
Expand Down
12 changes: 5 additions & 7 deletions tao/code/tao_command.f90
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ subroutine tao_command (command_line, err_flag, err_is_fatal)

use tao_set_mod, dummy2 => tao_command
use tao_change_mod, only: tao_change_var, tao_change_ele, tao_dmodel_dvar_calc, tao_change_tune, tao_change_z_tune
use tao_command_mod, only: tao_cmd_split, tao_re_execute, tao_next_switch
use tao_command_mod, only: tao_cmd_split, tao_re_execute, tao_next_switch, tao_next_word
use tao_data_and_eval_mod, only: tao_to_real
use tao_scale_mod, only: tao_scale_cmd
use tao_wave_mod, only: tao_wave_cmd
Expand Down Expand Up @@ -659,7 +659,7 @@ subroutine tao_command (command_line, err_flag, err_is_fatal)
! "-1" is a universe index and not a switch.
if (cmd_line(1:1) == '-' .and. cmd_line(1:2) /= '-1') then
call tao_next_switch (cmd_line, [character(20) :: '-update', '-lord_no_set', '-mask', &
'-branch', '-listing', '-silent'], .true., switch, err_flag, ix)
'-branch', '-listing', '-silent'], .true., switch, err_flag)
if (err_flag) return
select case (switch)
case ('-update')
Expand All @@ -669,11 +669,9 @@ subroutine tao_command (command_line, err_flag, err_is_fatal)
case ('-lord_no_set')
lord_set = .false.
case ('-branch')
branch_str = cmd_line(:ix)
call string_trim(cmd_line(ix+1:), cmd_line, ix)
call tao_next_word(cmd_line, branch_str)
case ('-mask')
mask = cmd_line(:ix)
call string_trim(cmd_line(ix+1:), cmd_line, ix)
call tao_next_word(cmd_line, mask)
case ('-silent')
silent = .true.
end select
Expand All @@ -686,7 +684,7 @@ subroutine tao_command (command_line, err_flag, err_is_fatal)
'universe', 'curve', 'graph', 'beam_init', 'wave', 'plot', 'bmad_com', 'element', 'opti_de_param', &
'csr_param', 'floor_plan', 'lat_layout', 'geodesic_lm', 'default', 'key', 'particle_start', &
'plot_page', 'ran_state', 'symbolic_number', 'beam', 'beam_start', 'dynamic_aperture', &
'global', 'region', 'calculate', 'space_charge_com', 'ptc_com', 'tune', 'z_tune'], .true., switch, err_flag, ix)
'global', 'region', 'calculate', 'space_charge_com', 'ptc_com', 'tune', 'z_tune'], .true., switch, err_flag)
if (err_flag) return
set_word = switch
enddo
Expand Down
63 changes: 49 additions & 14 deletions tao/code/tao_command_mod.f90
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,43 @@ end subroutine tao_cmd_split
!----------------------------------------------------------------------
!----------------------------------------------------------------------
!+
! Subroutine tao_next_switch (line, switch_list, return_next_word, switch, err, ix_word, neg_num_not_switch, print_err)
! Subroutine tao_next_word (line, word)
!
! Routine to return the next word in a line.
!
! Words are delimited by a space character except if the space is within quotes.
! Additionally, spaces within brackets "(...)", "{...}", and "[...]" are ignored.
! Outer quote marks will be removed in the returned word.
!
! Input:
! line -- character(*): String to parse.
!
! Output:
! line -- character(*): String with first word removed.
! word -- character(*): First word of line.
!-

subroutine tao_next_word (line, word)

implicit none

integer ix_word
character(*) line, word
character(1) delim
logical delim_found

!

call word_read (line, ' ', word, ix_word, delim, delim_found, line, .true.)
word = unquote(word)

end subroutine tao_next_word

!----------------------------------------------------------------------
!----------------------------------------------------------------------
!----------------------------------------------------------------------
!+
! Subroutine tao_next_switch (line, switch_list, return_next_word, switch, err, neg_num_not_switch, print_err)
!
! Subroutine look at the next word on the command line and match this word to a list of "switches"
! given by the switch_list argument.
Expand Down Expand Up @@ -314,10 +350,9 @@ end subroutine tao_cmd_split
! See above for more details.
! err -- logical: Set True if the next word begins with '-' but there is no match
! to anything in switch_list.
! ix_word -- integer: Character length of first word left on line.
!-

subroutine tao_next_switch (line, switch_list, return_next_word, switch, err, ix_word, neg_num_not_switch, print_err)
subroutine tao_next_switch (line, switch_list, return_next_word, switch, err, neg_num_not_switch, print_err)

implicit none

Expand All @@ -326,7 +361,7 @@ subroutine tao_next_switch (line, switch_list, return_next_word, switch, err, ix
logical err
logical, optional :: neg_num_not_switch

integer i, ix, n, ix_word
integer i, ix, n
logical, optional :: print_err
logical return_next_word
character(1) quote_mark, switch_start_char
Expand All @@ -341,8 +376,8 @@ subroutine tao_next_switch (line, switch_list, return_next_word, switch, err, ix
switch_start_char = ' '
endif

call string_trim(line, line, ix_word)
if (ix_word == 0) return
call string_trim(line, line, ix)
if (ix == 0) return

! If quoted string...

Expand All @@ -352,7 +387,7 @@ subroutine tao_next_switch (line, switch_list, return_next_word, switch, err, ix
if (line(i:i) /= quote_mark) cycle
if (line(i-1:i-1) == '\') cycle ! '
switch = line(2:i-1)
call string_trim(line(i+1:), line, ix_word)
call string_trim(line(i+1:), line, ix)
return
enddo

Expand All @@ -363,28 +398,28 @@ subroutine tao_next_switch (line, switch_list, return_next_word, switch, err, ix
! If not a switch...

if ((line(1:1) /= switch_start_char .and. switch_start_char /= ' ') .or. &
(logic_option(.false., neg_num_not_switch) .and. is_real(line(1:ix_word)))) then
(logic_option(.false., neg_num_not_switch) .and. is_real(line(1:ix)))) then
if (return_next_word) then
switch = line(1:ix_word)
call string_trim(line(ix_word+1:), line, ix_word)
switch = line(1:ix)
call string_trim(line(ix+1:), line, ix)
endif
return
endif

! It is a switch...

call match_word (line(:ix_word), switch_list, n, .true., matched_name=switch)
call match_word (line(:ix), switch_list, n, .true., matched_name=switch)
if (n < 1) then
err = .true.
if (n == 0) then
if (logic_option(.true., print_err)) call out_io (s_error$, r_name, 'UNKNOWN SWITCH: ' // line(:ix_word))
if (logic_option(.true., print_err)) call out_io (s_error$, r_name, 'UNKNOWN SWITCH: ' // line(:ix))
else
call out_io (s_error$, r_name, 'AMBIGUOUS SWITCH: ' // line(:ix_word))
call out_io (s_error$, r_name, 'AMBIGUOUS SWITCH: ' // line(:ix))
endif
return
endif

call string_trim(line(ix_word+1:), line, ix_word)
call string_trim(line(ix+1:), line, ix)

end subroutine tao_next_switch

Expand Down
14 changes: 6 additions & 8 deletions tao/code/tao_python_cmd.f90
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ subroutine tao_python_cmd (input_str)
use location_encode_mod, only: location_encode
use twiss_and_track_mod, only: twiss_and_track_at_s
use wall3d_mod, only: calc_wall_radius
use tao_command_mod, only: tao_next_switch, tao_cmd_split
use tao_command_mod, only: tao_next_switch, tao_cmd_split, tao_next_word
use tao_init_data_mod, only: tao_point_d1_to_data
use tao_init_variables_mod, only: tao_point_v1_to_var, tao_var_stuffit2
use tao_c_interface_mod, only: tao_c_interface_com, re_allocate_c_double
Expand Down Expand Up @@ -200,7 +200,7 @@ subroutine tao_python_cmd (input_str)
tao_c_interface_com%n_int = 0

do
call tao_next_switch (line, [character(8):: '-append ', '-write', '-noprint'], .false., switch, err, ix)
call tao_next_switch (line, [character(8):: '-append ', '-write', '-noprint'], .false., switch, err)
if (err) return
if (switch == '') exit

Expand All @@ -209,11 +209,9 @@ subroutine tao_python_cmd (input_str)
doprint = .false.

case ('-append', '-write')
call string_trim(line, line, ix)
file_name = line(:ix)
call string_trim(line(ix+1:), line, ix)

call tao_next_word(line, file_name)
iu_write = lunget()

if (switch == '-append') then
open (iu_write, file = file_name, position = 'APPEND', status = 'UNKNOWN', recl = 500)
else
Expand Down Expand Up @@ -6449,7 +6447,7 @@ subroutine tao_python_cmd (input_str)

case ('shape_manage')

call tao_next_switch (line, [character(12):: 'lat_layout', 'floor_plan'], .false., switch, err, ix_line)
call tao_next_switch (line, [character(12):: 'lat_layout', 'floor_plan'], .false., switch, err)
select case (switch)
case ('lat_layout')
drawing => s%plot_page%lat_layout
Expand All @@ -6463,7 +6461,7 @@ subroutine tao_python_cmd (input_str)
n = size(drawing%ele_shape)
ix = parse_int(line, err, 1, n+1); if (err) return

call tao_next_switch (line, [character(8):: 'add', 'delete'], .false., switch, err, ix_line)
call tao_next_switch (line, [character(8):: 'add', 'delete'], .false., switch, err)
select case (switch)
case ('add')
call move_alloc (drawing%ele_shape, shapes_temp)
Expand Down
5 changes: 2 additions & 3 deletions tao/code/tao_show_cmd.f90
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ subroutine tao_show_cmd (what)
! See if the results need to be written to a file.

do
call tao_next_switch (what2, [character(16):: '-append', '-write', '-noprint', '-no_err_out'], .false., switch, err, ix)
call tao_next_switch (what2, [character(16):: '-append', '-write', '-noprint', '-no_err_out'], .false., switch, err)
if (err) return
if (switch == '') exit

Expand All @@ -50,8 +50,7 @@ subroutine tao_show_cmd (what)
err_out = .false.

case ('-append', '-write')
file_name = what2(:ix)
call string_trim(what2(ix+1:), what2, ix)
call tao_next_word(what2, file_name)

ix = index(file_name, '*')
if (ix /= 0) then
Expand Down
Loading

0 comments on commit d725dbd

Please sign in to comment.