ic_pp.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,740 行 · 第 1/5 页

ERL
1,740
字号
    %%===============================================================%%===============================================================%%===============================================================%% Include macro%%%% Read the included file %%===============================================================%%===============================================================%%===============================================================include(File, IncDir) ->    case include2(File) of	{ok, FileName, Rem, Nl, FileType} ->	    %% The error handling is lite strange just to make it compatible to gcc	    case {read_inc_file(FileName, IncDir), Nl, FileType} of		{{ok, FileList, FileNamePath}, _, _} ->		    {ok, FileNamePath, FileList, Rem, Nl};		{{error, Text}, _, own_file} ->		    NameNl = count_nl(FileName,0),		    Error = lists:flatten(io_lib:format("~s: ~s",[FileName,Text])),		    {error, Rem, Nl, Error,  NameNl};		{{error, Text}, 1, sys_file} ->		    NameNl = count_nl(FileName,0),		    Error = lists:flatten(io_lib:format("~s: ~s",[FileName,Text])),		    {error, Rem, Nl, Error,  NameNl};		{{error, _Text}, _, sys_file} ->		    {error, Rem, Nl, "`#include' expects \"FILENAME\" or <FILENAME>"}	    end;	{error, {_Removed, Rem, Nl}} ->	    {error, Rem, Nl, "`#include' expects \"FILENAME\" or <FILENAME>"}    end.count_nl([],Nl) ->    Nl;count_nl([$\n|T],Nl) ->    count_nl(T,Nl+1);count_nl([_H|T],Nl) ->    count_nl(T,Nl).%%=================================================%% Extract the file name from the token list%%=================================================include2([space|Rem]) ->    include2(Rem);include2([{string, FileName}]) ->    {ok, FileName, [], 1, own_file};include2([{string, FileName}, space]) ->    {ok, FileName, [], 1, own_file};include2([{string, FileName}, {nl, _X} | Rem]) ->    {ok, FileName, Rem, 1, own_file};include2([{string, FileName}, space, {nl, _X} | Rem]) ->    {ok, FileName, Rem, 1, own_file};include2([{string, _FileName}, _No_nl | Rem]) ->    {error, read_to_nl(Rem)};include2([{string_part, File_part}, {nl, _X} | Rem]) ->     case include_read_string_file_name(File_part++[$\n], Rem, 1) of	 {ok, FileName, Rem2, Nl} ->	     {ok, FileName, Rem2, Nl, own_file};	 error ->	     {error, read_to_nl([{string_part,File_part} | Rem])}     end;include2([{sys_head, FileName}]) ->    {ok, FileName, [], 1, sys_file};include2([{sys_head, FileName}, space]) ->    {ok, FileName, [], 1, sys_file};include2([{sys_head, FileName}, {nl, _X}  | Rem]) ->    {ok, FileName, Rem, 1, sys_file};include2([{sys_head, FileName}, space, {nl, _X}  | Rem]) ->    {ok, FileName, Rem, 1, sys_file};include2([{sys_head, _FileName}, _No_nl | Rem]) ->    {error, read_to_nl(Rem)};include2([{sys_head_part ,File_part}, {nl, _X} | Rem]) ->     case include_read_sys_file_name(File_part++[$\n], Rem, 1) of	 {ok, FileName, Rem2, Nl} ->	     {ok, FileName, Rem2, Nl, sys_file};	 error ->	     {error, read_to_nl([{sys_head_part, File_part} | Rem])}     end;include2(Rem) ->    {error, read_to_nl(Rem)}.%%-------------------------------------------------  %% File name framed by " "%%-------------------------------------------------  include_read_string_file_name(File, [{string, File_part}, {nl,_X} | Rem], Nl) ->    {ok, File++File_part, Rem, Nl+1};include_read_string_file_name(File, [{string_part, File_part}, {nl,_X} | Rem], Nl) ->    include_read_string_file_name(File++File_part++[$\n], Rem, Nl+1);include_read_string_file_name(_File, _X, _Nl) ->    error.%%-------------------------------------------------  %% File name framed by < >%%-------------------------------------------------  include_read_sys_file_name(File, [{sys_head, File_part}, {nl,_X} | Rem], Nl) ->    {ok, File++File_part, Rem, Nl+1};include_read_sys_file_name(File, [{sys_head_part, File_part}, {nl,_X} | Rem], Nl) ->    include_read_sys_file_name(File++File_part++[$\n], Rem, Nl+1);include_read_sys_file_name(_File, _X, _Nl) ->    error.%%===============================================================%%===============================================================%%===============================================================%% Line macro%%%% The line macro may redefine both the current line number and %% the current file name: #line ' new_line_nr'  'new_file_name'%%===============================================================%%===============================================================%%===============================================================line(File, L, FN) ->    line(File, L, FN, not_defined, not_defined).line([], L, FN, _Line, _File) ->    {{line, error}, {[],[],0}, {FN,L,"invalid format `#line' directive"}};line([space|Rem], L, FN, Line, File) ->    line(Rem, L, FN, Line, File);%%------------------------------%% Line number expected%%------------------------------line([{number,Number}|Rem], L, FN, not_defined, File) ->    case catch list_to_integer(Number) of	{'EXIT', _} ->	    {{line, error}, read_to_nl(Rem), {FN,L,"invalid format `#line' directive"}};	Int ->	    line(Rem, L, FN, Int, File)    end;line(Rem, L, FN, not_defined, _File) ->    {{line, error}, read_to_nl(Rem), {FN,L,"invalid format `#line' directive"}};%%------------------------------%% File name or newline expected%%------------------------------line([{nl, _NL}|Rem], _L, FN, Line, not_defined) ->    {{line, ok}, {[],Rem,1}, Line, FN, io_lib:format("~n~p ~p #",[FN, Line-1])};line([{string,NewFN}|Rem], _L, _FN, Line, not_defined) ->    {{line, ok}, read_to_nl(Rem), Line, NewFN, io_lib:format("~n~p ~p #",[NewFN, Line-1])};line(Rem, L, FN, _Line, _File) ->    {{line, error}, read_to_nl(Rem), {FN,L,"invalid format `#line' directive"}}.    %%======================================================================================%%======================================================================================%%======================================================================================%% Source line%%%%%% Output:  {Str, Err, War, Rem, SelfRef}%%%% Description: The input source line is searched for macros. If a macro is found it%%              is expanded. The result of an expansion is rescanned for more macros.%%              To prevent infinite loops if the macro is self referring%%              an extra token is put into the Rem list. The variable SelfRef%%              contains all the macros which are inhibited to be expanded.%%              A special specae token is also inserted to prevent not wanted %%              concatinations if one of the variables to be concatinated is expanded.%%======================================================================================%%======================================================================================%%======================================================================================source_line(Str, Rem, SelfRef, Defs, Err, War, L, FN) ->    {Rem2, Para, No_of_para} = case read_para(Rem) of				   {ok, RemT, ParaT, No_of_paraT} ->				       {RemT, ParaT, No_of_paraT};				   {error, illegal_arg} ->				       {[], [], 0}			       end,    %%-------------------------------------------------      %% Check if a valid macro    %%-------------------------------------------------      case lists:keysearch(Str, 1, Defs) of	%% a macro without parameters	{value, {Str, 0, _MacroPara, Macro}} ->	    case lists:member(Str, SelfRef) of		true ->		    {[Str], Err, War, Rem, SelfRef};		false ->		    ExpandedRes2 = sl_mark_expanded(Macro, Str),		    {[], Err, War, ExpandedRes2 ++ [{self_ref,Str}|Rem], [Str|SelfRef]}	    end;	%% a macro with parameters	{value, {Str, N, _MacroPara, Macro}} when N == No_of_para ->	    case lists:member(Str, SelfRef) of		true ->		    {[Str], Err, War, Rem, SelfRef};		false ->		    ExpandedRes = sl_macro_expand(Macro, Para, Defs),		    ExpandedRes2 = sl_mark_expanded(ExpandedRes, Str),		    {[], Err, War, ExpandedRes2 ++ [{self_ref,Str}|Rem2], [Str|SelfRef]}	    end;	%% a variable, because it doesn't have any parameters	{value, {Str, _N, _MacroPara, _Macro}} when No_of_para == 0 ->	    {Str, Err, War, Rem, SelfRef};	%% illegal no of parameters	{value, {Str, N, _MacroPara, _Macro}} when No_of_para < N ->	    Text = io_lib:format(" macro `~s' used with just ~p arg",[Str,No_of_para]),	    Err2 = {FN, L, lists:flatten(Text)},	    {Str, [Err2|Err], War, Rem, SelfRef};	{value, {Str, _N, _MacroPara, _Macro}} ->	    Text = io_lib:format(" macro `~s' used with too many (~p) args",[Str,No_of_para]),	    Err2 = {FN, L, lists:flatten(Text)},	    {Str, [Err2|Err], War, Rem, SelfRef};	%% no macro	false ->	    {Str, Err, War, Rem, SelfRef}    end.%%=================================================%% Expand a macro%%=================================================sl_macro_expand(Macro, Para, Defs) ->    sl_macro_expand(Macro, Para, Defs, []).%%...................%% End%%...................sl_macro_expand([], _Para, _Defs, Res) ->    lists:reverse(Res);%%...................%% Concatination%%...................%% para ## para sl_macro_expand([{para, N}, space, {char,$#}, {char,$#}, space, {para,M} | T], Para, Defs, Res) ->    Exp = sl_para_para({para, N},{para, M}, Para),    sl_macro_expand(Exp++T, Para, Defs, [space |Res]);%% para## para sl_macro_expand([{para, N}, {char,$#}, {char,$#}, space, {para,M} | T], Para, Defs, Res) ->    Exp = sl_para_para({para, N},{para, M}, Para),    sl_macro_expand(Exp++T, Para, Defs, [space |Res]);%% para ##para sl_macro_expand([{para, N}, space, {char,$#}, {char,$#}, {para,M} | T], Para, Defs, Res) ->    Exp = sl_para_para({para, N},{para, M}, Para),    sl_macro_expand(Exp++T, Para, Defs, [space |Res]);%% para##para sl_macro_expand([{para, N}, {char,$#}, {char,$#}, {para,M} | T], Para, Defs, Res) ->    Exp = sl_para_para({para, N},{para, M}, Para),    sl_macro_expand(Exp++T, Para, Defs, [space |Res]);%% para ## var sl_macro_expand([{para, N}, space, {char,$#}, {char,$#}, space, {var, Var}|T], Para, Defs, Res) ->    Exp = sl_para_var({para, N}, {var, Var}, Para),    sl_macro_expand(Exp++T, Para, Defs, [space |Res]);%% para## var sl_macro_expand([{para, N}, {char,$#}, {char,$#}, space, {var, Var} | T], Para, Defs, Res) ->    [{var, VarN}] = lists:nth(N,Para),    sl_macro_expand(T, Para, Defs, [{expanded,Var},{expanded,VarN}, space |Res]);%% para ##var sl_macro_expand([{para, N}, space, {char,$#}, {char,$#}, {var, Var} | T], Para, Defs, Res) ->    [{var, VarN}] = lists:nth(N,Para),    sl_macro_expand(T, Para, Defs, [{expanded,Var},{expanded,VarN}, space |Res]);%% para##var sl_macro_expand([{para, N}, {char,$#}, {char,$#}, {var, Var} | T], Para, Defs, Res) ->    [{var, VarN}] = lists:nth(N,Para),    sl_macro_expand(T, Para, Defs, [{expanded,Var},{expanded,VarN}, space |Res]);%% var ## para sl_macro_expand([{var, Var}, space, {char,$#}, {char,$#}, space, {para,M} | T], Para, Defs, Res) ->    Exp = sl_var_para({var, Var},{para, M}, Para),    sl_macro_expand(Exp++T, Para, Defs, [space |Res]);%% var## para sl_macro_expand([{var, Var}, {char,$#}, {char,$#}, space, {para,M} | T], Para, Defs, Res) ->    Exp = sl_var_para({var, Var},{para, M}, Para),    sl_macro_expand(Exp++T, Para, Defs, [space |Res]);%% var ##para sl_macro_expand([{var, Var}, space, {char,$#}, {char,$#}, {para,M} | T], Para, Defs, Res) ->    Exp = sl_var_para({var, Var},{para, M}, Para),    sl_macro_expand(Exp++T, Para, Defs, [space |Res]);%% var##para sl_macro_expand([{var, Var}, {char,$#}, {char,$#}, {para,M} | T], Para, Defs, Res) ->    Exp = sl_var_para({var, Var},{para, M}, Para),    sl_macro_expand(Exp++T, Para, Defs, [space |Res]);%% expanded ## para sl_macro_expand([space, {char,$#}, {char,$#}, space, {para,M} | T], Para, Defs, [{expanded, Var}|Res]) ->    [{var, VarM}] = lists:nth(M,Para),    sl_macro_expand(T, Para, Defs, [{expanded,VarM},{expanded,Var} |Res]);%% expanded## para sl_macro_expand([{char,$#}, {char,$#}, space, {para,M} | T], Para, Defs, [{expanded, Var}|Res]) ->    [{var, VarM}] = lists:nth(M,Para),    sl_macro_expand(T, Para, Defs, [{expanded,VarM},{expanded,Var} |Res]);%% expanded ##para sl_macro_expand([space, {char,$#}, {char,$#}, {para,M} | T], Para, Defs, [{expanded, Var}|Res]) ->    [{var, VarM}] = lists:nth(M,Para),    sl_macro_expand(T, Para, Defs, [{expanded,VarM},{expanded,Var} |Res]);%% expanded##para sl_macro_expand([{char,$#}, {char,$#}, {para,M} | T], Para, Defs, [{expanded, Var}|Res]) ->    [{var, VarM}] = lists:nth(M,Para),    sl_macro_expand(T, Para, Defs, [{expanded,VarM},{expanded,Var} |Res]);%% para ## ? sl_macro_expand([{para, N}, space, {char,$#}, {char,$#}, space, X | T], Para, Defs, Res) ->    Reexp = sl_macro_reexpand(lists:nth(N,Para), Defs, []),    sl_macro_expand([X, space|T], Para, Defs, lists:flatten([Reexp, space|Res]));%% para## ? sl_macro_expand([{para, N}, {char,$#}, {char,$#}, space, X | T], Para, Defs, Res) ->    Reexp = sl_macro_reexpand(lists:nth(N,Para), Defs, []),    sl_macro_expand([X, space|T], Para, Defs, lists:flatten([Reexp, space|Res]));%% para ##? sl_macro_expand([{para, N}, space, {char,$#}, {char,$#}, X | T], Para, Defs, Res) ->    Reexp = sl_macro_reexpand(lists:nth(N,Para), Defs, []),    sl_macro_expand([X, space|T], Para, Defs, lists:flatten([Reexp, space|Res]));%% para##? sl_macro_expand([{para, N}, {char,$#}, {char,$#}, X | T], Para, Defs, Res) ->    Reexp = sl_macro_reexpand(lists:nth(N,Para), Defs, []),    sl_macro_expand([X, space|T], Para, Defs, lists:flatten([Reexp, space|Res]));sl_macro_expand([{char,$#}, {char,$#}, space |T], Para, Defs, [space|Res]) ->    sl_macro_expand(T, Para, Defs, Res);sl_macro_expand([{char,$#}, {char,$#} |T], Para, Defs, [space|Res]) ->    sl_macro_expand(T, Para, Defs, Res);sl_macro_expand([{char,$#}, {char,$#}, space |T], Para, Defs, Res) ->    sl_macro_expand(T,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?