-module(shlex). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/shlex.gleam"). -export([split/1]). -export_type([lex_error/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -type lex_error() :: unclosed_quotation | no_escaped_character. -file("src/shlex.gleam", 136). ?DOC(" Merge the character buffer into a token and push it onto the accumulator\n"). -spec push_buffer(list(binary()), list(binary())) -> list(binary()). push_buffer(Buf, Acc) -> case Buf of [] -> Acc; _ -> [begin _pipe = Buf, _pipe@1 = lists:reverse(_pipe), gleam@string:join(_pipe@1, <<""/utf8>>) end | Acc] end. -file("src/shlex.gleam", 108). -spec double_quote(list(binary()), list(binary()), list(binary())) -> {ok, list(binary())} | {error, lex_error()}. double_quote(Input, Acc, Buf) -> case Input of [] -> {error, unclosed_quotation}; [<<"\\"/utf8>>, C | Rest] -> case C of <<"\n"/utf8>> -> double_quote(Rest, Acc, Buf); <<"$"/utf8>> -> double_quote(Rest, Acc, [C | Buf]); <<"`"/utf8>> -> double_quote(Rest, Acc, [C | Buf]); <<"\""/utf8>> -> double_quote(Rest, Acc, [C | Buf]); <<"\\"/utf8>> -> double_quote(Rest, Acc, [C | Buf]); _ -> double_quote(Rest, Acc, [<<"\\"/utf8, C/binary>> | Buf]) end; [<<"\""/utf8>> | Rest@1] -> word(Rest@1, Acc, Buf); [Hd | Rest@2] -> double_quote(Rest@2, Acc, [Hd | Buf]) end. -file("src/shlex.gleam", 92). -spec single_quote(list(binary()), list(binary()), list(binary())) -> {ok, list(binary())} | {error, lex_error()}. single_quote(Input, Acc, Buf) -> case Input of [] -> {error, unclosed_quotation}; [<<"'"/utf8>> | Rest] -> word(Rest, Acc, Buf); [Hd | Rest@1] -> single_quote(Rest@1, Acc, [Hd | Buf]) end. -file("src/shlex.gleam", 63). -spec word(list(binary()), list(binary()), list(binary())) -> {ok, list(binary())} | {error, lex_error()}. word(Input, Acc, Buf) -> case Input of [] -> continue([], push_buffer(Buf, Acc)); [<<"\\"/utf8>>] -> {error, no_escaped_character}; [<<"\\"/utf8>>, <<"\n"/utf8>> | Rest] -> word(Rest, Acc, Buf); [<<"\\"/utf8>>, Next | Rest@1] -> word(Rest@1, Acc, [Next | Buf]); [<<"'"/utf8>> | Rest@2] -> single_quote(Rest@2, Acc, Buf); [<<"\""/utf8>> | Rest@3] -> double_quote(Rest@3, Acc, Buf); [<<" "/utf8>> | Rest@4] -> continue(Rest@4, push_buffer(Buf, Acc)); [<<"\t"/utf8>> | Rest@4] -> continue(Rest@4, push_buffer(Buf, Acc)); [<<"\n"/utf8>> | Rest@4] -> continue(Rest@4, push_buffer(Buf, Acc)); [Hd | Rest@5] -> word(Rest@5, Acc, [Hd | Buf]) end. -file("src/shlex.gleam", 52). -spec comment(list(binary()), list(binary())) -> {ok, list(binary())} | {error, lex_error()}. comment(Input, Acc) -> case Input of [] -> continue([], Acc); [<<"\n"/utf8>> | Rest] -> continue(Rest, Acc); [_ | Rest@1] -> comment(Rest@1, Acc) end. -file("src/shlex.gleam", 38). -spec continue(list(binary()), list(binary())) -> {ok, list(binary())} | {error, lex_error()}. continue(Input, Acc) -> case Input of [] -> _pipe = Acc, _pipe@1 = lists:reverse(_pipe), {ok, _pipe@1}; [<<" "/utf8>> | Rest] -> continue(Rest, Acc); [<<"\t"/utf8>> | Rest] -> continue(Rest, Acc); [<<"\n"/utf8>> | Rest] -> continue(Rest, Acc); [<<"#"/utf8>> | Rest@1] -> comment(Rest@1, Acc); _ -> word(Input, Acc, []) end. -file("src/shlex.gleam", 34). ?DOC( " Split a shell input into a list of string tokens.\n" " \n" " This aims to follow the POSIX standard defined by IEEE Std 1003.1-2024.\n" " \n" " ## Examples\n" " \n" " ```gleam\n" " let assert Ok(tokens) = split(\"git commit -m 'hello world!'\")\n" " assert tokens == [\"git\", \"commit\", \"-m\", \"hello worlds!\"]\n" " ```\n" ). -spec split(binary()) -> {ok, list(binary())} | {error, lex_error()}. split(Input) -> _pipe = Input, _pipe@1 = gleam@string:to_graphemes(_pipe), continue(_pipe@1, []).