Select the types of activity you want to include in your feed.
Lots of fixes
- Aliasing in Morbig was slightly broken and is now hackily fixed. - Exporting of environment variables was slightly broken - Subshell exit codes were not quite right either
···1111 C.
1212 {
1313 interactive;
1414+ subshell = false;
1415 state =
1516 Merry_posix.State.make
1617 ~home:(Sys.getenv "HOME" ^ "/")
+11-3
src/lib/built_ins.ml
···4646 | Dot of string (* a.k.a source *)
4747 | Unset of [ `Variables of string list | `Functions of string list ]
4848 | Hash of hash
4949- | Command of string list
4949+ | Command of { print_command : bool; args : string list }
5050+ | Alias
5151+ | Unalias
50525153(* Change Directory *)
5254module Cd = struct
···199201 let doc = "Arguments to command." in
200202 Arg.(value & pos_all string [] & info [] ~docv:"ARGS" ~doc)
201203204204+ let print_command =
205205+ let doc = "Write a string to stdout of the command we would use." in
206206+ Arg.(value & flag & info [ "v"; "V" ] ~docv:"V" ~doc)
207207+202208 let t =
203203- let make_command pos_all = Command pos_all in
204204- let term = Term.(const make_command $ args) in
209209+ let make_command print_command args = Command { print_command; args } in
210210+ let term = Term.(const make_command $ print_command $ args) in
205211 let info =
206212 let doc = "Execute a simple command." in
207213 Cmd.info "command" ~doc
···258264 | "unset" :: _ as cmd -> exec_cmd cmd Unset.t
259265 | "hash" :: _ as cmd -> exec_cmd cmd Hash.t
260266 | "command" :: _ as cmd -> exec_cmd cmd Command.t
267267+ | "alias" :: _ -> Some (Ok Alias)
268268+ | "unalias" :: _ -> Some (Ok Unalias)
261269 | _ -> None
+3-1
src/lib/built_ins.mli
···2323 | Dot of string
2424 | Unset of [ `Variables of string list | `Functions of string list ]
2525 | Hash of hash
2626- | Command of string list
2626+ | Command of { print_command : bool; args : string list }
2727+ | Alias
2828+ | Unalias
27292830val of_args : string list -> (t, string) result option
2931(** Parses a command-line to the built-ins, errors are returned if parsing. *)
+108-40
src/lib/eval.ml
···30303131 type ctx = {
3232 interactive : bool;
3333+ subshell : bool;
3334 state : S.t;
3435 local_state : (string * string) list;
3536 executor : E.t;
···174175175176 let resolve_program ?(update = true) ctx name =
176177 let v =
177177- if not (String.contains name '/') then
178178- Sys.getenv_opt "PATH"
178178+ (* Fmt.epr "Resolving %s\n%!" name; *)
179179+ if not (String.contains name '/') then begin
180180+ (* Fmt.epr "not %a\n%!" Fmt.(option string) (S.lookup ctx.state ~param:"PATH" |> Option.map Ast.word_components_to_string); *)
181181+ S.lookup ctx.state ~param:"PATH"
182182+ |> Option.map Ast.word_components_to_string
179183 |> Option.value ~default:"/bin:/usr/bin"
180184 |> String.split_on_char ':'
181185 |> List.find_map (fun dir ->
182186 let p = Filename.concat dir name in
187187+ (* Fmt.epr "Does it exist %s %b\n%!" p (Sys.file_exists p); *)
183188 if Sys.file_exists p then Some p else None)
189189+ end
184190 else if Sys.file_exists name then Some name
185191 else None
186192 in
···201207 List.fold_left (fun acc (k, _) -> List.remove_assoc k acc) env extra
202208 |> List.append extra
203209210210+ let remove_quotes s =
211211+ let s_len = String.length s in
212212+ if s.[0] = '"' && s.[s_len - 1] = '"' then String.sub s 1 (s_len - 2) else s
213213+204214 let rec handle_pipeline ~async initial_ctx pipeline_switch p : ctx Exit.t =
205215 let mode = if async then Types.Async else Types.Switched pipeline_switch in
206216 let set_last_background ~async process ctx =
···229239 in
230240 let exec_process ctx job ?fds ?stdin ~stdout ~pgid executable args =
231241 let ctx, process =
232232- match resolve_program ctx executable with
233233- | ctx, None ->
234234- Fmt.epr "msh: command not found: %s\n%!" executable;
242242+ match (executable, resolve_program ctx executable) with
243243+ | _, (ctx, None) | "", (ctx, _) ->
244244+ Eunix.with_redirections
245245+ (match fds with None -> [] | Some ls -> ls)
246246+ (fun () ->
247247+ Eio.Flow.copy_string
248248+ (Fmt.str "msh: command not found: %s\n" executable)
249249+ stdout);
235250 (ctx, Error (127, `Not_found))
236236- | ctx, Some full_path ->
251251+ | _, (ctx, Some full_path) ->
237252 ( ctx,
238253 E.exec ctx.executor ?fds ?stdin ~stdout ~pgid ~mode
239254 ~cwd:(cwd_of_ctx ctx)
···265280 | Ast.SimpleCommand (Named (executable, suffix)) :: rest -> (
266281 let ctx, executable = expand_cst ctx executable in
267282 let executable = handle_word_cst_subshell ctx executable in
283283+ let executable, extra_args =
284284+ (* This is a side-effect of the alias command with something like
285285+ alias ls="ls -la" *)
286286+ match executable with
287287+ | [ Ast.WordLiteral s ] as v -> (
288288+ match String.split_on_char ' ' (remove_quotes s) with
289289+ | exec :: args ->
290290+ ( [ Ast.WordName exec ],
291291+ List.map
292292+ (fun w -> Ast.Suffix_word [ Ast.WordName w ])
293293+ args )
294294+ | _ -> (v, []))
295295+ | v -> (v, [])
296296+ in
268297 let executable = Ast.word_components_to_string executable in
269298 let ctx, suffix =
270299 match suffix with
271300 | None -> (ctx, [])
272301 | Some suffix -> expand_redirects (ctx, []) suffix
273302 in
274274- let ctx, args = args ctx suffix in
303303+ let ctx, args = args ctx (extra_args @ suffix) in
275304 let args_as_strings = List.map Ast.word_components_to_string args in
276305 let some_read, some_write =
277306 stdout_for_pipeline ~sw:pipeline_switch ctx rest
···294323 | Some (Error _) ->
295324 (ctx, handle_job ~pgid job (`Built_in (Exit.nonzero () 1)))
296325 | (None | Some (Ok (Command _))) as v -> (
297297- let is_command =
298298- match v with Some (Ok (Command _)) -> true | _ -> false
326326+ let is_command, command_args, print_command =
327327+ match v with
328328+ | Some (Ok (Command { print_command; args })) ->
329329+ (true, args, print_command)
330330+ | _ -> (false, [], false)
299331 in
300332 (* We handle the [export] built_in explicitly as we need access to the
301333 raw CST *)
···324356 in
325357 loop saved_ctx job (pgid, some_read) rest
326358 | None -> (
327327- let executable, args =
359359+ let exec_and_args =
328360 if is_command then begin
329329- match args_as_strings with
330330- | [] -> ("", [])
331331- | [ x ] -> (x, [])
332332- | x :: xs -> (x, xs)
361361+ match command_args with
362362+ | [] -> assert false
363363+ | x :: xs -> (
364364+ Eunix.with_redirections rdrs @@ fun () ->
365365+ match resolve_program ~update:false ctx x with
366366+ | _, None -> Exit.nonzero ("", []) 1
367367+ | _, Some prog ->
368368+ if print_command then
369369+ Exit.zero ("echo", [ prog ])
370370+ else Exit.zero (x, xs))
333371 end
334334- else (executable, args_as_strings)
372372+ else Exit.zero (executable, args_as_strings)
335373 in
336336- match stdout_of_previous with
337337- | None ->
338338- let ctx, job =
339339- exec_process ctx job ~fds:rdrs ~stdout:some_write
340340- ~pgid executable args
374374+ match exec_and_args with
375375+ | Exit.Nonzero _ as v ->
376376+ let job =
377377+ handle_job ~pgid job (`Built_in (v >|= fun _ -> ()))
341378 in
342342- close_stdout ~is_global some_write;
343379 loop ctx job (pgid, some_read) rest
344344- | Some stdout ->
345345- let ctx, job =
346346- exec_process ctx job ~fds:rdrs ~stdin:stdout
347347- ~stdout:some_write ~pgid executable
348348- args_as_strings
349349- in
350350- close_stdout ~is_global some_write;
351351- loop ctx job (pgid, some_read) rest)))
380380+ | Exit.Zero (executable, args) -> (
381381+ match stdout_of_previous with
382382+ | None ->
383383+ let ctx, job =
384384+ exec_process ctx job ~fds:rdrs
385385+ ~stdout:some_write ~pgid executable args
386386+ in
387387+ close_stdout ~is_global some_write;
388388+ loop ctx job (pgid, some_read) rest
389389+ | Some stdout ->
390390+ let ctx, job =
391391+ exec_process ctx job ~fds:rdrs ~stdin:stdout
392392+ ~stdout:some_write ~pgid executable
393393+ args_as_strings
394394+ in
395395+ close_stdout ~is_global some_write;
396396+ loop ctx job (pgid, some_read) rest))))
352397 | Some (Ok bi) ->
353398 let ctx = handle_built_in ~rdrs ~stdout:some_write ctx bi in
354399 close_stdout ~is_global some_write;
···361406 in
362407 (* TODO: No way this is right *)
363408 let ctx = handle_compound_command ctx c in
409409+ let job = handle_job ~pgid job (`Built_in (ctx >|= fun _ -> ())) in
364410 loop (Exit.value ctx) job (pgid, None) rest
365411 | FunctionDefinition (name, (body, _rdrs)) :: rest ->
366412 let ctx = { ctx with functions = (name, body) :: ctx.functions } in
···512558 ))
513559 | Ast.VariableAtom (s, UseAlternativeValue (_, alt)) -> (
514560 match S.lookup ctx.state ~param:s with
515515- | Some cst -> expand (cst :: acc) ctx rest
516516- | None -> expand (alt :: acc) ctx rest)
561561+ | Some _ -> expand (alt :: acc) ctx rest
562562+ | None -> expand ([ Ast.WordEmpty ] :: acc) ctx rest)
517563 | Ast.VariableAtom (s, AssignDefaultValues (_, value)) -> (
518564 match S.lookup ctx.state ~param:s with
519565 | Some cst -> expand (cst :: acc) ctx rest
···529575 | Ast.WordSingleQuoted cst :: rest ->
530576 let new_ctx, cst_acc = expand [] ctx cst in
531577 expand ([ Ast.WordSingleQuoted cst_acc ] :: acc) new_ctx rest
578578+ | Ast.WordAssignmentWord (n, w) :: rest ->
579579+ let new_ctx, cst_acc = expand [] ctx w in
580580+ expand ([ Ast.WordAssignmentWord (n, cst_acc) ] :: acc) new_ctx rest
532581 | v :: rest -> expand ([ v ] :: acc) ctx rest
533582 in
534583 expand [] ctx ast
···543592 state = S.update ~export:true acc_ctx.state ~param v;
544593 }
545594 rest
546546- | _ :: _ -> Exit.nonzero_msg acc_ctx "export weird arguments"
595595+ | Ast.WordName param :: rest -> (
596596+ match S.lookup acc_ctx.state ~param with
597597+ | Some v ->
598598+ loop
599599+ {
600600+ acc_ctx with
601601+ state = S.update ~export:true acc_ctx.state ~param v;
602602+ }
603603+ rest
604604+ | None -> loop acc_ctx rest)
605605+ | c :: _ ->
606606+ Exit.nonzero_msg acc_ctx "export weird arguments: %s\n"
607607+ (Ast.word_component_to_string c)
547608 in
548609 List.fold_left
549610 (fun ctx w -> match ctx with Exit.Zero ctx -> loop ctx w | _ -> ctx)
···593654 f @@ handle_pipeline ~async ctx sw p
594655 | Noand_or, Nlist.Cons ((p, next_sep), rest) ->
595656 let f, p = pipeline p in
596596- fold (next_sep, f (handle_pipeline ~async ctx sw p)) rest
657657+ let exit_status = f (handle_pipeline ~async ctx sw p) in
658658+ fold (next_sep, exit_status) rest
597659 | And, Nlist.Cons ((p, next_sep), rest) -> (
598660 match exit_so_far with
599661 | Exit.Zero ctx ->
···654716 | Ast.Subshell (term, sep) ->
655717 let saved_ctx = ctx in
656718 let e = exec ctx (term, Some sep) in
657657- e >|= fun _ -> saved_ctx
719719+ let v = e >|= fun _ -> saved_ctx in
720720+ v
658721 | _ as c ->
659722 Fmt.epr "Compound command not supported: %a\n%!" yojson_pp
660723 (Ast.compound_command_to_yojson c);
···682745 let stdout = Eio.Flow.buffer_sink buf in
683746 let r, w = Eio_unix.pipe sw in
684747 Eio.Fiber.fork ~sw (fun () -> Eio.Flow.copy r stdout);
685685- let subshell_ctx = { ctx with stdout = w } in
686686- let _ = run (Exit.zero subshell_ctx) s in
748748+ let subshell_ctx = { ctx with stdout = w; subshell = true } in
749749+ let sub_ctx, _ = run (Exit.zero subshell_ctx) s in
687750 Eio.Flow.close w;
688688- (ctx, Buffer.contents buf)
751751+ ((sub_ctx >|= fun _ -> ctx), Buffer.contents buf)
689752 in
690753 let rec run_subshells ~sw ran_subshell = function
691754 | [] -> []
···781844 let should_exit =
782845 { Exit.default_should_exit with interactive = `Yes }
783846 in
784784- Exit.nonzero_msg ~should_exit ctx ~exit_code:n "exit"
847847+ Exit.nonzero ~should_exit ctx n
785848 | Set { update; print_options } ->
786849 let v =
787850 Exit.zero
···826889 Eio.Flow.copy_string (Fmt.str "%a" Hash.pp ctx.hash) stdout;
827890 Exit.zero ctx
828891 | _ -> assert false)
892892+ | Alias | Unalias -> Exit.zero ctx (* Morbig handles this for us *)
829893 | Command _ ->
830894 (* Handled separately *)
831895 assert false
···891955 match
892956 ( should_exit.interactive,
893957 should_exit.non_interactive,
894894- ctx.interactive )
958958+ ctx.subshell,
959959+ ctx.interactive,
960960+ commands )
895961 with
896896- | `Yes, _, true | _, `Yes, false -> Stdlib.exit exit_code
962962+ | `Yes, _, false, true, [] | _, `Yes, false, false, [] ->
963963+ if should_exit.interactive = `Yes then Fmt.epr "exit\n%!";
964964+ Stdlib.exit exit_code
897965 | _ -> loop_commands (exit, c :: cs) commands)
898966 | Exit.Zero _ as ctx -> loop_commands (ctx, c :: cs) commands)
899967 in
+4
src/lib/exit.ml
···5353let is_nonzero = function Zero _ -> false | Nonzero _ -> true
5454let is_zero = function Zero _ -> true | Nonzero _ -> false
55555656+let pp ppf = function
5757+ | Zero _ -> Fmt.string ppf "zero"
5858+ | Nonzero _ -> Fmt.string ppf "nonzero"
5959+5660module Syntax = struct
5761 let ( >|= ) x f = map ~f x
5862 let ( let+ ) = ( >|= )
+13-5
src/lib/posix/state.ml
···99 variables : (bool * Merry.Ast.word_cst) Variables.t;
1010}
11111212+let update ?(export = false) t ~param v =
1313+ let variables' = Variables.add param (export, v) t.variables in
1414+ { t with variables = variables' }
1515+1616+let seed_env () =
1717+ let env = Merry.Eunix.env () in
1818+ List.fold_left
1919+ (fun vars (param, v) ->
2020+ Variables.add param (true, [ Merry.Ast.WordName v ]) vars)
2121+ Variables.empty env
2222+1223let make ?(functions = []) ?(root = 0) ?(outermost = true) ?(home = "/root")
1313- ?(variables = Variables.empty) cwd =
2424+ ?variables cwd =
2525+ let variables = match variables with None -> seed_env () | Some v -> v in
1426 { cwd; functions; root; outermost; home; variables }
15271628let cwd t = t.cwd
1729let set_cwd t cwd = { t with cwd }
1830let expand t = function `Tilde -> t.home
1931let lookup t ~param = Variables.find_opt param t.variables |> Option.map snd
2020-2121-let update ?(export = false) t ~param v =
2222- let variables' = Variables.add param (export, v) t.variables in
2323- { t with variables = variables' }
24322533let remove ~param t =
2634 match Variables.find_opt param t.variables with
+42
test/built_ins.t
···174174 out.txt
175175 test.sh
176176 testing
177177+178178+ $ msh -c "command -v ls | xargs -- basename"
179179+ ls
180180+181181+182182+ $ sh -c "command -v skjdlksjdlkwjdlkw"
183183+ [1]
184184+ $ msh -c "command -v skjdlksjdlkwjdlkw"
185185+ [1]
186186+187187+8. Alias
188188+189189+This is mostly handled by Morbig, but we have had to do some fixes...
190190+191191+ $ rm *.txt
192192+ $ cat > test.sh << EOF
193193+ > ls
194194+ > alias ls="ls -a"
195195+ > ls
196196+ > unalias ls
197197+ > ls
198198+ > EOF
199199+200200+ $ sh test.sh
201201+ test.sh
202202+ testing
203203+ .
204204+ ..
205205+ test.sh
206206+ testing
207207+ test.sh
208208+ testing
209209+ $ msh test.sh
210210+ test.sh
211211+ testing
212212+ .
213213+ ..
214214+ test.sh
215215+ testing
216216+ test.sh
217217+ testing
218218+
+13-1
test/simple.t
···6565 $ msh -c "export FOO=bar; env | grep FOO"
6666 FOO=bar
67676868+Trying a common pattern for path-like expansion:
6969+7070+ $ cat > test.sh << EOF
7171+ > export TPATH=/usr/bin
7272+ > export TPATH=/bin:\$TPATH
7373+ > echo \$TPATH
7474+ > EOF
7575+7676+ $ sh test.sh
7777+ /bin:/usr/bin
7878+ $ msh test.sh
7979+ /bin:/usr/bin
8080+68812. Pipelines with And|Or
698270832.1 Simple Or
···8699for example the command not being found here :/
8710088101 $ msh -c "lssssss 2>&1 > /dev/null | echo 'all good'"
8989- msh: command not found: lssssss
90102 all good
91103921042.2 Simple And
+11-4
vendor/morbig.0.11.0/src/aliases.ml
···1212open Parser
1313open Parser.MenhirInterpreter
14141515+type ctx =
1616+ | OutsideOfSimpleCommand
1717+ | ExpectingCommandName
1818+ | AfterCommandName
1919+1520let perform default f =
1621 if not (Options.disable_alias_expansion ()) then f () else default
1722···164169 if lhs production = X (N N_linebreak) || lhs production = X (N N_word) then
165170 about_to_reduce_cmd_name (resume checkpoint)
166171 else
167167- lhs production = X (N N_cmd_name)
172172+ lhs production = X (N N_cmd_name)
168173 | InputNeeded _ ->
169174 let dummy = Lexing.dummy_pos in
170175 let token = NAME (Name "a_word"), dummy, dummy in
···229234(** [alias_substitution aliases checkpoint word] substitutes an
230235 alias by its definition if word is not a reserved word and
231236 if the parsing context is about to reduce a [cmd_name]. *)
232232-let alias_substitution aliases checkpoint word =
237237+let alias_substitution aliases checkpoint word ctx =
233238 perform (aliases, word) @@ fun () ->
234239 if about_to_reduce_cmd_name checkpoint
235240 && not (Keyword.is_reserved_word word)
236236- then
241241+ && (!ctx = ExpectingCommandName)
242242+ then begin
237243 let word = substitute aliases word in
244244+ ctx := OutsideOfSimpleCommand;
238245 only_if_end_with_whitespace word aliases CommandNameSubstituted
239239- else
246246+ end else
240247 if about_to_reduce_word checkpoint
241248 && inside_a_substitution_combo aliases.state
242249 then
+6-1
vendor/morbig.0.11.0/src/aliases.mli
···1515type t
1616type aliases = t
17171818+type ctx =
1919+ | OutsideOfSimpleCommand
2020+ | ExpectingCommandName
2121+ | AfterCommandName
2222+1823(** [empty] is an empty alias table. *)
1924val empty : t
2025···3338 alias by its definition if [word] is not a reserved word and
3439 if the parsing context is about to reduce a [cmd_name]. *)
3540val alias_substitution :
3636- t -> 'a Parser.MenhirInterpreter.checkpoint -> string -> t * string
4141+ t -> 'a Parser.MenhirInterpreter.checkpoint -> string -> ctx ref -> t * string
+22-15
vendor/morbig.0.11.0/src/engine.ml
···2424type state = {
2525 checkpoint : program located checkpoint;
2626 aliases : Aliases.t;
2727+ alias_ctx : Aliases.ctx ref;
2728 }
28292930module type Lexer =
···4344 (** Parsing loop. *)
4445 (**--------------**)
45464646- let rec parse csts { aliases; checkpoint } =
4747+ let rec parse csts { aliases; checkpoint; alias_ctx } =
4748 match checkpoint with
4849 (**
4950···5455 *)
5556 | InputNeeded _parsing_state ->
5657 let (token, ps, pe, aliases) =
5757- Lexer.next_token { aliases; checkpoint }
5858+ Lexer.next_token { aliases; checkpoint; alias_ctx }
5859 in
5959- parse csts { aliases; checkpoint = offer checkpoint (token, ps, pe) }
6060+ parse csts { aliases; checkpoint = offer checkpoint (token, ps, pe); alias_ctx }
60616162 (**
6263···8788 else
8889 cst :: csts
8990 in
9090- parse csts { aliases; checkpoint }
9191+ parse csts { aliases; checkpoint; alias_ctx }
9192 end
92939394 (**
···132133133134 *)
134135 | HandlingError _env ->
135135- parse csts { aliases; checkpoint = resume checkpoint }
136136+ parse csts { aliases; checkpoint = resume checkpoint; alias_ctx }
136137137138 (**
138139···174175 *)
175176 | AboutToReduce (env, production) ->
176177 let nt = nonterminal_of_production production in
178178+ let aliax_ctx =
179179+ if nt = AnyN N_simple_command then begin
180180+ alias_ctx := Aliases.ExpectingCommandName
181181+ end
182182+ in
177183178184 let rec reject_cmd_words_which_are_reserved_words () =
179185 if is_cmd () && top_is_keyword () then parse_error ()
···191197 on_top_symbol env { perform = interpret_alias_command }
192198 else
193199 let checkpoint = resume checkpoint in
194194- parse csts { aliases; checkpoint }
200200+ parse csts { aliases; checkpoint; alias_ctx }
195201 and interpret_alias_command: type a. a symbol * a -> _ = function
196202 | N N_complete_command, cst ->
197203 let aliases = Aliases.interpret aliases cst in
198204 let checkpoint = resume checkpoint in
199199- parse csts { aliases; checkpoint }
205205+ parse csts { aliases; checkpoint; alias_ctx }
200206 | _ ->
201207 assert false (* By correctness of the underlying LR automaton. *)
202208 in
···209215210216 *)
211217 | Shifting (_, _, _) ->
212212- parse csts { aliases; checkpoint = resume checkpoint }
218218+ parse csts { aliases; checkpoint = resume checkpoint; alias_ctx }
213219214220 and parse_error : type a. unit -> a = fun () ->
215221 raise (Errors.DuringParsing (Lexer.current_position ()))
216222 in
217223 parse [] {
218224 aliases = Aliases.empty;
219219- checkpoint = entry_point (Lexer.current_position ())
225225+ checkpoint = entry_point (Lexer.current_position ());
226226+ alias_ctx = ref Aliases.OutsideOfSimpleCommand
220227 }
221228222229let recognize_word_if_relevant checkpoint word =
···276283 let previous_token ?(n = 0) () =
277284 ExtPervasives.list_nth_opt !tokens n
278285279279- let rec next_token { aliases; checkpoint } =
286286+ let rec next_token { aliases; checkpoint; alias_ctx } =
280287 if HDL.inside_here_document () then (
281288 !push_pretoken (HDL.next_here_document (lexbuf ()) (current ()));
282282- next_token { aliases; checkpoint }
289289+ next_token { aliases; checkpoint; alias_ctx }
283290 )
284291 else
285292 let (pretoken, pstart, pstop) as p = !next_pretoken () in
···320327 rules, or applies globally.
321328322329 *)
323323- let new_aliases, w = alias_substitution aliases checkpoint w0 in
330330+ let new_aliases, w = alias_substitution aliases checkpoint w0 alias_ctx in
324331 let word =
325332 if w == w0 then
326333 WORD (Word (w, List.(flatten (map parse_pattern cst))))
···376383 the here-document lexing mode. *)
377384 if HDL.next_line_is_here_document () then (
378385 HDL.start_here_document_lexing ();
379379- next_token { aliases; checkpoint }
386386+ next_token { aliases; checkpoint; alias_ctx }
380387 )
381388382389 (** If the input is completed, [NEWLINE] is interpreted
···408415 pos_cnum = p.pos_cnum
409416 }
410417411411- let next_token ({ aliases; checkpoint } as state) =
418418+ let next_token ({ aliases; checkpoint; alias_ctx } as state) =
412419 let curr_p = copy_position (lexbuf ()).Lexing.lex_curr_p in
413413- let state' = { aliases; checkpoint } in
420420+ let state' = { aliases; checkpoint; alias_ctx } in
414421 let (raw, _, _, aliases) as token = next_token state' in
415422 let state = { state with aliases } in
416423 tokens := raw :: !tokens;