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 + -
显示快捷键?