%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1997-2012. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
%%
%% %CopyrightEnd%
%%
%%----------------------------------------------------------------------
%% Purpose : The purpouse of the converter process is to take
%% care of the raw data that is received by the tracing
%% process (a pman_shell process) and pass it on to
%% the buffer process in chunks that can be handled.
%%
%% This module is a part of the buffering system, and
%% should not be used except through the API defined
%% in the pman_buf module.
%%
%%----------------------------------------------------------------------
-module(pman_buf_converter).
-compile([{nowarn_deprecated_function,{gs,start,0}}]).
%%-compile(export_all).
-export([init/2]).
-include("pman_buf.hrl").
%% ---------------------------------------------------------------
%% Starts the process which received the raw data from the debugger,
%% cuts and forwards it to the buffer in smaller chunks. High priority
%% to avoid large message queues waiting to be processed.
init(Buffer_Pid, FileName) ->
process_flag(priority, max),
converter_loop(Buffer_Pid,[],0,true,[], FileName).
converter_loop(Buffer_Pid,Raw,Size,State,Last, FileName) ->
receive
{file,Shell} ->
case init_file(lists:append(Raw,Last),
FileName,
Shell,
Buffer_Pid) of
true -> converter_loop(Buffer_Pid,
[to_buffer],
1,
State,
[],
FileName);
false -> converter_loop(Buffer_Pid,
Raw,
Size,
State,
Last,
FileName)
end;
{raw,Trace} ->
{New_Raw,New_Size,New_State,New_Last} =
converter_data(Trace, Buffer_Pid, Raw, Size, State, Last),
converter_loop(Buffer_Pid,
New_Raw,
New_Size,
New_State,
New_Last,
FileName);
{buffer,accept} when Raw /= [] ->
{Length,Rest,Print} = pman_buf_utils:split(Raw,?PRINT_LEN,0,[]),
Buffer_Pid!{raw,Print,Length},
converter_loop(Buffer_Pid,Rest,Size-Length,false,Last,FileName);
{buffer,accept} when Last /= [] ->
{New_Raw,New_Size,New_State,New_Last} =
converter_data(Last,Buffer_Pid,Raw,Size,true,[]),
converter_loop(Buffer_Pid,
New_Raw,
New_Size,
New_State,
New_Last,
FileName);
{buffer,accept} ->
converter_loop(Buffer_Pid,Raw,Size,true,Last, FileName);
{clear,Str} ->
Buffer_Pid!{clear,Str},
converter_loop(Buffer_Pid,[],0,State,Last,FileName)
end.
converter_data(Trace,Buffer_Pid,Raw,Size,State,Last) ->
if
?BUFF_SIZE - Size > 0 ->
{Len,Rest,New_Trace} = pman_buf_utils:split(Trace,
?BUFF_SIZE-Size,
0,[]),
{New_Raw,New_Last} =
case Rest of
[] ->
{lists:append(Raw,New_Trace),Last};
[_|_] ->
case Last of
[] ->
{lists:append(Raw,New_Trace),Rest};
_ ->{lists:concat([Raw,New_Trace,[cut_buffer]]),
Rest}
end
end,
case State of true ->
{Length,Cut_Raw,Print} = pman_buf_utils:split(New_Raw,
?PRINT_LEN,
0,[]),
Buffer_Pid!{raw,Print,Length},
{Cut_Raw,Size-Length,false,New_Last};
_ ->
{New_Raw,Size+Len,false,New_Last}
end;
true ->
{Raw,Size,State,Trace}
end.
%% ---------------------------------------------------------------
%% Initializes the environment for saving the trace to file. The
%% actual saving is taken care of by the buffer process.
init_file(Raw,FileName, Name,Buffer_Pid) ->
case open_file(FileName, Name) of
{false,T} ->
pman_win:msg_win(T),
false;
{File,T} ->
Buffer_Pid!{converter,file},
pman_win:dialog_window(gs:start(),T),
save_loop_init(File,Raw)
end.
open_file(FileName, _Shell) ->
%% L = "pman_trace." ++ Shell,
case file:open(FileName, [read,write]) of
{error, _} ->
Str = "ERROR: Could not create_file\n" ++ FileName,
{false,Str};
{ok,File} ->
file:position(File, {eof, 0}),
Str1 = " Appending trace log to file\n" ++ FileName,
{File,Str1}
end.
save_loop_init(Fd,Raw) ->
{Date, Time} = calendar:local_time(),
{Year, Month, Day} = Date,
{Hour, Minute, Second} = Time,
io:format(Fd,"%%% ~n",[]),
io:format(Fd,"%%% Trace output~n",[]),
io:format(Fd,"%%% Started at ~4p-~2p-~2p ~2p:~2p:~2p~n",
[Year, Month, Day,
Hour, Minute, Second
]),
io:format(Fd,"%%% ~n~n",[]),
Print = lists:map(fun(X) -> pman_buf_utils:textformat(X) end, Raw),
receive
{buffer,Text} when is_list(Text) ->
io:format(Fd,Text,[]),
io:format(Fd,Print,[]),
save_loop(Fd)
end.
save_loop(Fd) ->
receive
{raw,Raw} ->
Print = lists:map(fun(X) -> pman_buf_utils:textformat(X) end, Raw),
io:format(Fd,Print,[]),
save_loop(Fd);
buffer -> true
end.