From 84adefa331c4159d432d22840663c38f155cd4c1 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Fri, 20 Nov 2009 14:54:40 +0000 Subject: The R13B03 release. --- lib/pman/src/pman_buf_converter.erl | 189 ++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 lib/pman/src/pman_buf_converter.erl (limited to 'lib/pman/src/pman_buf_converter.erl') diff --git a/lib/pman/src/pman_buf_converter.erl b/lib/pman/src/pman_buf_converter.erl new file mode 100644 index 0000000000..b6f560411c --- /dev/null +++ b/lib/pman/src/pman_buf_converter.erl @@ -0,0 +1,189 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 1997-2009. 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(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. + + + + + -- cgit v1.2.3