ic_pp.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,740 行 · 第 1/5 页
ERL
1,740 行
end;expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN) when Command == "endif" -> {_Removed, Rem2, Nl} = read_to_nl(Rem), case Endif of 1 -> Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN); _ -> IfCou2 = {endif, Endif-1, IfLine}, expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err, War, L+Nl, FN) end;expand([{command,_Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN) -> {_Removed, Rem2, _Nl} = read_to_nl(Rem), IfCou2 = {endif, Endif, IfLine}, expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err, War, L, FN);%% Solves a bug when spaces in front of hashmark !expand([space | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN) -> expand(Rem, Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN);expand([{nl,_Nl} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN) -> expand(Rem, Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN);expand([_X | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN) -> {_Removed, Rem2, Nl} = read_to_nl(Rem), Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN);%%---------------------------------------%% Check all tokens%%---------------------------------------expand([{nl, _N} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> expand(Rem, [$\n | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L+1, FN);expand([space | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> expand(Rem, [?space | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([space_exp | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> expand(Rem, [?space | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L, FN) -> case pp_command(Command, Rem, Defs, IncDir, Err, War, L, FN) of {define, Rem2, Defs2, Err2, War2, Nl} -> Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs2, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN); {undef, Rem2, Defs2, Err2, War2, Nl} -> Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs2, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN); {{include, ok}, FileName, FileCont, Rem2, Nl, Err2, War2} -> {Out3, Defs3, Err3, War3} = run_include(FileName, FileCont, Out, Defs, Err2, War2, L+Nl, IncFile, IncDir), Nls = [], Out4 = Out3++Nls++Out, expand(Rem2, Out4, SelfRef, Defs3, IncFile, IncDir, check_all, Err3, War3, L+Nl, FN); {{include, error}, Rem2, Nl, Err2, War2} -> Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN); {{ifdef, true}, Rem2, Err2, War2, Nl} -> Out2 = [lists:duplicate(Nl,$\n)|Out], IfCou2 = {endif, 1, L}, expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, IfCou2, Err2, War2, L+Nl, FN); {{ifdef, false}, Rem2, Err2, War2, Nl} -> Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN); {{ifndef, true}, Rem2, Err2, War2, Nl} -> Out2 = [lists:duplicate(Nl,$\n)|Out], IfCou2 = {endif, 1, L}, expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, IfCou2, Err2, War2, L+Nl, FN); {{ifndef, false}, Rem2, Err2, War2, Nl} -> Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN); {endif, Rem2, Err2, War2, Nl} -> Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN); {{'if', true}, Rem2, Err2, War2, Nl} -> Out2 = [lists:duplicate(Nl,$\n)|Out], IfCou2 = {endif, 1, L}, expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, IfCou2, Err2, War2, L+Nl, FN);%% {{'if', false}, Removed, Rem2, Nl} -> Not implemented at present {{'if', error}, Rem2, Err2, War2, Nl} -> Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err2, War2, L+Nl, FN); {'else', {_Removed, Rem2, Nl}} -> Out2 = [lists:duplicate(Nl,$\n)|Out], Err2 = {FN, L, "`else' command is not implemented at present"}, expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, [Err2|Err], War, L+Nl, FN); {'elif', {_Removed, Rem2, Nl}} -> Out2 = [lists:duplicate(Nl,$\n)|Out], Err2 = {FN, L, "`elif' command is not implemented at present"}, expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, [Err2|Err], War, L+Nl, FN); {warning, {WarningText, Rem2, Nl}} -> [FileName|_More] = IncFile, War2 = {FileName, L, "warning: #warning "++detokenise(WarningText)}, Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, [War2|War], L+Nl, FN); {error, {ErrorText, Rem2, Nl}} -> [FileName|_More] = IncFile, Err2 = {FileName, L, detokenise(ErrorText)}, Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, [Err2|Err], War, L+Nl, FN); {{line, ok}, {_Removed, Rem2, Nl}, L2, FN2, LineText} -> Out2 = lists:duplicate(Nl,$\n)++LineText++Out, [_X|IF] = IncFile, IncFile2 = [FN2|IF], expand(Rem2, Out2, SelfRef, Defs, IncFile2, IncDir, check_all, Err, War, L2, FN2); {{line, error}, {_Removed, Rem2, Nl}, Err2} -> Out2 = [lists:duplicate(Nl,$\n)|Out], expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, [Err2|Err], War, L+Nl, FN); hash_mark -> expand(Rem, Out, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L, FN); {pragma, Rem2, Nl, Text} -> Out2 = lists:duplicate(Nl,$\n)++Text++Out, expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN); {ident, Rem2, Nl, Text} -> Out2 = lists:duplicate(Nl,$\n)++Text++Out, expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN); {not_recognised, {Removed, Rem2, Nl}} -> Text = lists:reverse([$#|Command]), RemovedS = lists:reverse([?space|detokenise(Removed)]), Out2 = [$\n|RemovedS]++Text++Out, case Command of [X|_T] when ?is_upper(X) -> expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN); [X|_T] when ?is_lower(X) -> expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN); [X|_T] when ?is_underline(X) -> expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, Err, War, L+Nl, FN); _ -> Err2 = {FN, L, "invalid preprocessing directive name"}, expand(Rem2, Out2, SelfRef, Defs, IncFile, IncDir, check_all, [Err2|Err], War, L+Nl, FN) end; Else ->% io:format(" %%%%Else%%%%%% ~p~n",[Else]), exit(Else) end;expand([{var, "__LINE__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> LL = io_lib:format("~p",[L]), expand(Rem, [LL | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{var, "__FILE__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> expand(Rem, [$",FN,$" | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{var, "__DATE__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> {{Y,M,D},{_H,_Mi,_S}} = calendar:universal_time(), Date = io_lib:format("\"~s ~p ~p\"",[month(M),D,Y]), expand(Rem, [Date | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{var, "__TIME__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> {{_Y,_M,_D},{H,Mi,S}} = calendar:universal_time(), HS = if H < 10 -> "0"++integer_to_list(H); true -> integer_to_list(H) end, MiS = if Mi < 10 -> "0"++integer_to_list(Mi); true -> integer_to_list(Mi) end, SS = if S < 10 -> "0"++integer_to_list(S); true -> integer_to_list(S) end, Time = io_lib:format("\"~s:~s:~s\"",[HS,MiS,SS]), expand(Rem, [Time | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{var, "__INCLUDE_LEVEL__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> IL = io_lib:format("~p",[length(IncFile)-1]), expand(Rem, [IL | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{var, "__BASE_FILE__"}|Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> [BF|_T] = lists:reverse(IncFile), expand(Rem, [$",BF,$" | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{var, Var} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> {Out2, Err2, War2, Rem2, SelfRef2} = source_line(Var, Rem, SelfRef, Defs, Err, War, L, FN), expand(Rem2, [Out2 | Out], SelfRef2, Defs, IncFile, IncDir, IfCou, Err2, War2, L, FN);expand([{char, Char} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> expand(Rem, [Char | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{number, Number} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> expand(Rem, [Number | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{expanded, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> expand(Rem, [Str | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{self_ref, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> SelfRef2 = lists:delete(Str,SelfRef), expand(Rem, Out, SelfRef2, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{string, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> expand(Rem, [$", Str, $" | Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN);expand([{string_part, Str} | Rem], Out, SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L, FN) -> {Str2, Rem2, Nl} = expand_string_part([$"|Str], Rem), expand(Rem2, [Str2| Out], SelfRef, Defs, IncFile, IncDir, IfCou, Err, War, L+Nl, FN).%%========================================================================%% Expand a line starting as a partial string%%========================================================================expand_string_part(Str, File) -> expand_string_part(File, Str, 0).expand_string_part([{string, Str_part} | Rem], Str, Nl) -> {Str++Str_part++[$"], Rem, Nl};expand_string_part([space | Rem], Str, Nl) -> expand_string_part(Rem, Str, Nl);expand_string_part([nl| Rem], Str, Nl) -> expand_string_part(Rem, Str++[$\n], Nl);expand_string_part([{string_part, Str_part} | Rem], Str, Nl) -> expand_string_part(Rem, Str++Str_part, Nl).%%========================================================================%% Parse and integrate command line macro directives%% At this momment, only -D and -U are supported (gcc like)%%======================================================================== %% Collect all command line macro definitionsget_cmd_line_defs(Flags) -> Adjusted = parse_cmd_line(Flags,[]), {_Out, _Err, _War, Defs, _IfCou} = expand(tokenise(Adjusted,""), [], [], [], [], [], check_all, [], [], 1, ""), Defs.%% Parse command line macrosparse_cmd_line([],Found) -> lists:flatten(lists:reverse(Found));parse_cmd_line([45,68|Rest],Found) -> {Collected,RestCmds} = collect_define(Rest,[]), parse_cmd_line(RestCmds,[Collected|Found]);parse_cmd_line([45,85|Rest],Found) -> {Collected,RestCmds} = collect_undefine(Rest,[]), parse_cmd_line(RestCmds,[Collected|Found]);parse_cmd_line([_|Rest],Found) -> parse_cmd_line(Rest,Found).%% Collect defines and translate them%% into a text format collect_define([],Found) -> { "#define "++lists:reverse(Found)++"\n", [] };collect_define([32|Rest],Found) -> { "#define "++lists:reverse(Found)++"\n", Rest };collect_define([61|Rest],[]) -> { "", Rest };collect_define([61|Rest],Found) -> collect_define(Rest,[32|Found]);collect_define([C|Rest],Found) -> collect_define(Rest,[C|Found]).%% Collect undefines and translate them%% into a text format collect_undefine([],Found) -> { "#undef "++lists:reverse(Found)++"\n", [] };collect_undefine([32|Rest],Found) -> { "#undef "++lists:reverse(Found)++"\n", Rest };collect_undefine([C|Rest],Found) -> collect_undefine(Rest,[C|Found]).%%======================================================================================%%======================================================================================%%======================================================================================%% Read a preprocessor command%%%%%% Output: Depending of the command, typically = {Command, Rem, Err, War, Nl}%%%%======================================================================================%%======================================================================================%%======================================================================================pp_command(Command, [space|File], Defs, IncDir, Err, War, L, FN) -> pp_command(Command, File, Defs, IncDir, Err, War, L, FN);pp_command(Command, File, Defs, IncDir, Err, War, L, FN) -> case Command of %%---------------------------------------- %% #define %%---------------------------------------- "define" -> case define(File, Err, War, L, FN) of {error, Rem, Err2, War2, Nl} -> {define, Rem, Defs, Err2, War2, Nl}; {warning, Rem, Name, No_of_para, Parameters, Macro, Err2, War2, Nl} ->
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?