@@ -24,14 +24,16 @@ module shlex_module
2424 public :: shlex
2525 interface shlex
2626 module procedure shlex_bool
27- module procedure shlex_error
27+ module procedure shlex_error
2828 end interface
2929
3030 ! Split: return split strings
3131 public :: split
3232 interface split
3333 module procedure split_bool
3434 module procedure split_error
35+ module procedure split_joined_bool
36+ module procedure split_joined_error
3537 end interface
3638
3739 ! Turn on verbosity for debugging
@@ -156,22 +158,100 @@ function split_error(pattern,error) result(list)
156158
157159 type (shlex_token), allocatable :: tokens(:)
158160
159- integer :: n,maxlen,i,l
160-
161161 tokens = shlex(pattern,error)
162+ call tokens_to_strings(tokens,list)
162163
164+ end function split_error
165+
166+ ! Convert a list of tokens to strings
167+ pure subroutine tokens_to_strings (tokens ,list )
168+ type (shlex_token), optional , intent (in ) :: tokens(:)
169+ character (kind= SCK,len= :), allocatable , intent (out ) :: list(:)
170+
171+ integer :: n,maxlen,i
172+
163173 n = size (tokens)
164174 maxlen = 0
175+
165176 do i= 1 ,n
166177 maxlen = max (maxlen,len (tokens(i)% string))
167178 end do
168179
169180 allocate (character (kind= SCK,len= maxlen) :: list(n))
170181 do i= 1 ,n
171182 list(i) = tokens(i)% string
172- end do
183+ end do
184+
185+ end subroutine tokens_to_strings
186+
187+ ! High level interface: also join spaced flags like -I /path -> -I/path
188+ function split_joined_bool (pattern , join_spaced , success ) result(list)
189+ character (* ), intent (in ) :: pattern
190+ logical , intent (in ) :: join_spaced
191+ logical , intent (out ) :: success
192+ character (kind= SCK,len= :), allocatable :: list(:)
193+ type (shlex_token) :: error
173194
174- end function split_error
195+ list = split_joined_error(pattern, join_spaced, error)
196+ success = error% type== NO_ERROR
197+
198+ end function split_joined_bool
199+
200+ ! High level interface: also join spaced flags like -I /path -> -I/path
201+ function split_joined_error (pattern , join_spaced , error ) result(list)
202+ character (* ), intent (in ) :: pattern
203+ type (shlex_token), intent (out ) :: error
204+ logical , intent (in ) :: join_spaced
205+ character (kind= SCK,len= :), allocatable :: list(:)
206+
207+ integer :: i, n, count
208+ type (shlex_token) :: tok, next_tok
209+ type (shlex_token), allocatable :: raw(:),joined(:)
210+
211+ raw = shlex(pattern,error)
212+
213+ if (error% type/= NO_ERROR .or. .not. join_spaced) then
214+
215+ call tokens_to_strings(raw,list)
216+
217+ else
218+
219+ n = size (raw)
220+
221+ allocate (joined(n))
222+ count = 0
223+ i = 1
224+
225+ old_tokens: do while (i <= n)
226+ tok = raw(i)
227+
228+ if (len_trim (tok% string)==2 ) then
229+
230+ if (tok% string (1 :1 ) == ' -' .and. &
231+ (tok% string (2 :2 ) >= ' A' .and. tok% string (2 :2 ) <= ' Z' .or. tok% string (2 :2 ) >= ' a' .and. tok% string (2 :2 ) <= ' z' )) then
232+ if (i + 1 <= n) then
233+ next_tok = raw(i + 1 )
234+ if (.not. (len_trim (next_tok% string) >= 1 .and. next_tok% string (1 :1 ) == ' -' )) then
235+ count = count + 1
236+ joined(count) = shlex_token(TOKEN_WORD,trim (tok% string)// trim (next_tok% string))
237+ i = i + 2
238+ cycle old_tokens
239+ end if
240+ end if
241+ endif
242+
243+ end if
244+
245+ count = count + 1
246+ joined(count) = tok
247+ i = i + 1
248+ end do old_tokens
249+
250+ call tokens_to_strings(joined(:count),list)
251+
252+ end if
253+
254+ end function split_joined_error
175255
176256 ! High level interface: return a list of tokens
177257 function shlex_bool (pattern ,success ) result(list)
0 commit comments