erlang - How do I pass a string to epp_dodger? -


i'm writing process erlang source code. pretty first line of program is:

{ok, forms} = epp_dodger:parse_file(filename) 

however, want simple unit testing. so: how persuade epp_dodger take input string instead of file?

alternatively, has epp_dodger:parse_form/2,3, takes iodevice, how provide iodevice on string?

the code below (which admittedly bit hackish) starts gen_server takes string argument, , fulfills erlang i/o protocol enough satisfy epp_dodger:parse/2 able read , parse string process.

here's example of using it:

1> {ok,p} = iostr:start("-module(x).\n-export([f/0]).\nf() -> ok.\n"). 2> epp_dodger:parse(p,1). {ok,[{tree,attribute,          {attr,1,[],none},          {attribute,              {tree,atom,{attr,1,[],none},module},              [{tree,atom,{attr,1,[],none},x}]}},      {tree,attribute,          {attr,2,[],none},          {attribute,              {tree,atom,{attr,2,[],none},export},              [{tree,list,                   {attr,2,[],none},                   {list,                       [{tree,arity_qualifier,                            {attr,2,[],none},                            {arity_qualifier,                                {tree,atom,{attr,...},f},                                {tree,integer,{...},...}}}],                       none}}]}},      {tree,function,          {attr,3,[],none},          {func,              {tree,atom,{attr,3,[],none},f},              [{tree,clause,                   {attr,3,[],none},                   {clause,[],none,[{atom,3,ok}]}}]}}]} 

the process dies once string exhausted.

note code misses few things — handling unicode properly, example — should give idea of how make more robust i/o server purpose if needed.

-module(iostr). -behaviour(gen_server).  -export([start_link/1, start/1, stop/1]).  -export([init/1, handle_call/3, handle_cast/2, handle_info/2,          terminate/2, code_change/3]).  -record(state, {           data,           line = 1,           lines          }).  start_link(data) ->     gen_server:start_link(?module, [data], []).  start(data) ->     gen_server:start(?module, [data], []).  stop(pid) ->     gen_server:cast(pid, stop).  init([data0]) ->     data = [line++"\n" || line <- string:tokens(data0, "\n")],     {ok, #state{data=data,lines=length(data)}}.  handle_call(_request, _from, state) ->     {reply, ok, state}.  handle_cast(stop, state) ->     {stop, normal, state}; handle_cast(_msg, state) ->     {noreply, state}.  handle_info({io_request,from,replyas,{get_until,_,_,_,_,_}},             #state{data=[],lines=l}=state) ->     ! {io_reply, replyas, {eof,l}},     {stop, normal, state}; handle_info({io_request,from,replyas,{get_until,_,_,m,f,args}},             #state{data=data,line=l}=state) ->     case handler(data,l,[],m,f,args) of         eof ->             lines = state#state.lines,             ! {io_reply, replyas, {eof,lines}},             {stop, normal, state#state{data=[]}};         {ok,result,rest,ndata,nl} ->             ! {io_reply, replyas, result},             case rest of                 [] ->                     {noreply, state#state{data=ndata,line=nl}};                 _ ->                     {noreply, state#state{data=[rest|ndata],line=nl}}             end     end; handle_info(_info, state) ->     {noreply, state}.  terminate(_reason, _state) ->     ok.  code_change(_oldvsn, state, _extra) ->     {ok, state}.  handler([input|data],l,cont,m,f,extra) ->     case catch apply(m,f,[cont,input|extra]) of         {done,eof,_} ->             eof;         {done,result,rest} ->             {ok,result,rest,data,l+1};         {more,ncont} ->             case data of                 [] -> eof;                 _ -> handler(data,l+1,ncont,m,f,extra)             end     end. 

Comments

Popular posts from this blog

android - Get AccessToken using signpost OAuth without opening a browser (Two legged Oauth) -

org.mockito.exceptions.misusing.InvalidUseOfMatchersException: mockito -

google shop client API returns 400 bad request error while adding an item -