Skip to content

Instantly share code, notes, and snippets.

@lujb
Created September 6, 2013 06:18
Show Gist options
  • Save lujb/6460167 to your computer and use it in GitHub Desktop.
Save lujb/6460167 to your computer and use it in GitHub Desktop.
Consult Erlang Conf String.
%%
%% Consult erlang conf string, same as file:consult/1.
%%
-module(conf).
-export([consult/1]).
consult(Str) when is_list(Str) ->
scan(Str).
%% Internal Functions.
scan(Str) ->
case erl_scan:string(Str)of
{ok, Tok, _} ->
parse(Tok);
{error, {N, Mod, Desc}, _L} ->
{error, {line(N), lists:concat(["error: ", Mod, ", desc: ", format_desc(erl_scan, Desc)])}}
end.
parse(Tok) ->
parse(Tok, [], []).
parse([], [], Rst) ->
{ok, lists:reverse(Rst)};
parse([], Acc, Rst) ->
do_parse([], Acc, Rst);
parse([T = {dot, _}|Rest], Acc, Rst)->
do_parse(Rest, [T|Acc], Rst);
parse([T|Rest], Acc, Rst)->
parse(Rest, [T|Acc], Rst).
do_parse(Tok, Acc, Rst) ->
case erl_parse:parse_term(lists:reverse(Acc)) of
{error, {N, Mod, Desc}} ->
{error, {line(N), lists:concat(["error: ", Mod, ", desc: ", format_desc(erl_parse, Desc)])}};
{ok, Term}->
parse(Tok, [], [Term | Rst])
end.
format_desc(M, Desc) ->
lists:flatten(M:format_error(Desc)).
line(N) when is_integer(N), N>0 -> N;
line(_N) -> 1.
%% Test Functions.
test(Fn) ->
io:format("consult:~p~n======~n", [file:consult(Fn)]),
{ok, B} = file:read_file(Fn),
consult(binary_to_list(B)).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment