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