···453453 | Some s when kind = `Smallest -> (so_far, Some s)
454454 | _ -> (
455455 let s = so_far ^ String.make 1 c in
456456- match Glob.test ~pattern [ s ] with
456456+ match Glob.tests ~pattern [ s ] with
457457 | [ s ] -> (s, Some s)
458458 | _ -> (s, acc)))
459459 ("", None) param
···468468 | Some s when kind = `Smallest -> (so_far, Some s)
469469 | _ -> (
470470 let s = String.make 1 c ^ so_far in
471471- match Glob.test ~pattern [ s ] with
471471+ match Glob.tests ~pattern [ s ] with
472472 | [ s ] -> (s, Some s)
473473 | _ -> (s, acc)))
474474 ("", None)
···711711 | Exit.Zero ctx -> exec ctx (e2, Some sep2)
712712 | Exit.Nonzero { value = ctx; _ } -> handle_else_part ctx else_part)
713713714714+ and handle_case_clause ctx = function
715715+ | Ast.Case _ -> Exit.zero ctx
716716+ | Cases (word, case_list) -> (
717717+ let ctx, word = expand_cst ctx word in
718718+ let scrutinee = Ast.word_components_to_string word in
719719+ let res =
720720+ Nlist.fold_left
721721+ (fun acc pat ->
722722+ match acc with
723723+ | Some _ as ctx -> ctx
724724+ | None -> (
725725+ match pat with
726726+ | Ast.Case_pattern _ -> assert false
727727+ | Ast.Case_compound (p, sub) ->
728728+ Nlist.fold_left
729729+ (fun inner_acc pattern ->
730730+ match inner_acc with
731731+ | Some _ as v -> v
732732+ | None ->
733733+ let ctx, pattern = expand_cst ctx pattern in
734734+ let pattern =
735735+ Ast.word_components_to_string pattern
736736+ in
737737+ if Glob.test ~pattern scrutinee then begin
738738+ Some (exec_subshell ctx sub)
739739+ end
740740+ else inner_acc)
741741+ None p))
742742+ None case_list
743743+ in
744744+ match res with Some ctx -> ctx | None -> Exit.zero ctx)
745745+746746+ and exec_subshell ctx (term, sep) =
747747+ let saved_ctx = ctx in
748748+ let e = exec ctx (term, Some sep) in
749749+ let v = e >|= fun _ -> saved_ctx in
750750+ v
751751+714752 and handle_compound_command ctx v : ctx Exit.t =
715753 match v with
716754 | Ast.ForClause fc -> handle_for_clause ctx fc
717755 | Ast.IfClause if_ -> handle_if_clause ctx if_
718756 | Ast.BraceGroup (term, sep) -> exec ctx (term, Some sep)
719719- | Ast.Subshell (term, sep) ->
720720- let saved_ctx = ctx in
721721- let e = exec ctx (term, Some sep) in
722722- let v = e >|= fun _ -> saved_ctx in
723723- v
757757+ | Ast.Subshell s -> exec_subshell ctx s
758758+ | Ast.CaseClause cases -> handle_case_clause ctx cases
724759 | _ as c ->
725760 Fmt.epr "Compound command not supported: %a\n%!" yojson_pp
726761 (Ast.compound_command_to_yojson c);
+6-2
src/lib/import.ml
···7575end
76767777module Glob = struct
7878- let test ~pattern s = List.filter Glob.(test (of_string pattern)) s
7979- let glob_dir ~pattern dir = test ~pattern (Eio.Path.read_dir dir)
7878+ let tests ~pattern s = List.filter Glob.(test (of_string pattern)) s
7979+8080+ let test ~pattern s =
8181+ match tests ~pattern [ s ] with [ _ ] -> true | _ :: _ | [] -> false
8282+8383+ let glob_dir ~pattern dir = tests ~pattern (Eio.Path.read_dir dir)
8084end
+39
test/cases.t
···11+Case compound command
22+33+ $ cat > test.sh << EOF
44+ >
55+ > service () {
66+ > case "\$1" in
77+ > start|begin)
88+ > echo "Starting up service..."
99+ > ;;
1010+ > status)
1111+ > echo "All good..."
1212+ > ;;
1313+ > stop)
1414+ > echo "Stopping service"
1515+ > ;;
1616+ > *)
1717+ > echo "Unknown command: \$1"
1818+ > ;;
1919+ > esac
2020+ > }
2121+ >
2222+ > service start
2323+ > service status
2424+ > service stop
2525+ > service foo
2626+ >
2727+ > EOF
2828+2929+ $ sh test.sh
3030+ Starting up service...
3131+ All good...
3232+ Stopping service
3333+ Unknown command: foo
3434+3535+ $ msh test.sh
3636+ Starting up service...
3737+ All good...
3838+ Stopping service
3939+ Unknown command: foo