Shells in OCaml
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

Simple globbing support

Using glob(3) this adds simple glob support. I'm sure this isn't
sufficient for all of the pattern-matching that is possible in POSIX
shell's, but it is a good start.

+39 -8
+1
TODO.md
··· 16 16 - [ ] Conditionals 17 17 - [ ] Substitutions 18 18 - [ ] Globs 19 + - [x] Simple support via glob(3) 19 20 - [ ] Traps 20 21 - [ ] Background Tasks 21 22 - [ ] Interactive Mode
+2
src/lib/ast.ml
··· 746 746 String.concat " " (List.map word_component_to_string s) 747 747 | WordSingleQuoted s -> 748 748 String.concat " " (List.map word_component_to_string s) 749 + | WordGlobAll -> "*" 750 + | WordGlobAny -> "?" 749 751 | v -> 750 752 Fmt.failwith "Conversion of %a" Yojson.Safe.pp 751 753 (word_component_to_yojson v)
+25 -8
src/lib/eval.ml
··· 203 203 204 204 let cwd_of_ctx ctx = S.cwd ctx.state |> Fpath.to_string |> ( / ) ctx.fs 205 205 206 + let needs_glob_expansion : Ast.word_component -> bool = function 207 + | WordGlobAll | WordGlobAny -> true 208 + | _ -> false 209 + 210 + let glob_expand wc = 211 + Ast.word_components_to_string wc |> Globlon.glob |> Array.to_list 212 + 213 + let args swc = 214 + List.concat_map 215 + (function 216 + | Ast.Suffix_redirect _ -> [] 217 + | Suffix_word wc -> 218 + if List.exists needs_glob_expansion wc then glob_expand wc 219 + else [ Ast.word_components_to_string wc ]) 220 + swc 221 + 206 222 let execute_commands initial_ctx local_switch p = 207 223 let rec loop ctx 208 224 ((status_of_previous, stdout_of_previous) : ··· 237 253 loop ctx (res, some_read) rest)) 238 254 | Ast.SimpleCommand (Named (executable, Some suffix)) :: rest -> ( 239 255 let args = 240 - List.filter_map 241 - (function 242 - | Ast.Suffix_word w -> 243 - Some 244 - (String.concat "" 245 - @@ List.map Ast.word_component_to_string w) 246 - | Ast.Suffix_redirect _ -> None) 247 - suffix 256 + args suffix 257 + (* List.filter_map *) 258 + (* (function *) 259 + (* | Ast.Suffix_word w -> *) 260 + (* Some *) 261 + (* (String.concat "" *) 262 + (* @@ List.map Ast.word_component_to_string w) *) 263 + (* | Ast.Suffix_redirect _ -> None) *) 264 + (* suffix *) 248 265 in 249 266 match 250 267 Built_ins.of_args (Ast.word_components_to_string executable :: args)
+11
test/paths.t
··· 1 + Here we test some specific semantics of how a shell should handle paths. In 2 + particular, things like globbing. 3 + 4 + $ touch hello.txt; touch world.txt 5 + $ osh -c "basename --suffix='.txt' *.txt" 6 + hello 7 + world 8 + $ touch Hello.txt 9 + $ osh -c "basename --suffix='.txt' ?ello.txt" 10 + Hello 11 + hello