ic_pp.erl

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

ERL
1,740
字号
%%---------------------------------------%% CR (just remove these)%%---------------------------------------token([$\r|File], L, Result, Gen, BsNl) ->%    Bs = lists:duplicate(BsNl+1,{nl,L}),    token(File, L, Result, Gen, BsNl); %% Bs or BsNl?%%---------------------------------------%% Newline%%---------------------------------------token([$\n|File], L, Result, _Gen, BsNl) ->    Bs = lists:duplicate(BsNl+1,{nl,L}),    token(File, L+1, Bs++Result, not_set, 0);token([$\\,$\n|File], L, Result, Gen, BsNl) ->    token(File, L, Result, Gen, BsNl+1);%%---------------------------------------%% Comments%%---------------------------------------token([$/,$/|File], L, Result, not_set, BsNl) ->    Rem = skip_to_nl(File),    token(Rem, L+1,[{nl, L} | Result], not_set, BsNl);token([$/,$/|File], L, Result, _Gen, BsNl) ->    Rem = skip_to_nl(File),    token(Rem, L+1,[{nl, L} | Result], not_set, BsNl);token([$/,$*|File], L, Result, not_set, BsNl) ->    case token_comment(File) of	{Rem, nl} ->	    token(Rem, L+1, [{nl, L} | Result], not_set, BsNl);	Rem ->	    token(Rem, L, Result, not_set, BsNl)    end;token([$/,$*|File], L, Result, Gen, BsNl) ->    case token_comment(File) of	{Rem, nl} ->	    token(Rem, L+1, [{nl, L}, space | Result], not_set, BsNl);	Rem ->	    token(Rem, L, [space|Result], Gen, BsNl)    end;%%---------------------------------------%% Variable%%---------------------------------------token([X|File], L, Result, Gen, BsNl) when ?is_upper(X) ->    GenNew = case Gen of not_set -> var; _ -> Gen end,    {Rem, Var} = tok_var(File, [X]),    token(Rem, L, [{var,Var}|Result], GenNew, BsNl);token([X|File], L, Result, Gen, BsNl) when ?is_lower(X) ->    GenNew = case Gen of not_set -> var; _ -> Gen end,    {Rem, Var} = tok_var(File, [X]),    token(Rem, L, [{var,Var}|Result], GenNew, BsNl);token([X|File], L, Result, Gen, BsNl) when ?is_underline(X) ->    GenNew = case Gen of not_set -> var; _ -> Gen end,    {Rem, Var} = tok_var(File, [X]),    token(Rem, L, [{var,Var}|Result], GenNew, BsNl);%%---------------------------------------%% Number%%---------------------------------------token([X|File], L, Result, Gen, BsNl) when ?is_number(X) ->    GenNew = case Gen of not_set -> number; _ -> Gen end,    {Rem, Tokens} = tok_number(File, [X]),    token(Rem, L, [{number,Tokens}|Result], GenNew, BsNl);%%---------------------------------------%% Space%%---------------------------------------token([X|File], L, [Y|Result], Gen, BsNl) when ?is_space(X) ->    case Y of	space ->	    Rem = remove_leading_spaces(File),	    token(Rem, L, [Y|Result], Gen, BsNl);	{nl,_,_} ->	    Rem = remove_leading_spaces(File),	    token(Rem, L, Result, Gen, BsNl);	_ ->	    Rem = remove_leading_spaces(File),	    token(Rem, L, [space, Y |Result], Gen, BsNl)    end;token([X|File], L, [Y|Result], Gen, BsNl) when ?is_tab(X) ->    case Y of	space ->	    Rem = remove_leading_spaces(File),	    token(Rem, L, [Y|Result], Gen, BsNl);	{nl,_,_} ->	    Rem = remove_leading_spaces(File),	    token(Rem, L, Result, Gen, BsNl);	_ ->	    Rem = remove_leading_spaces(File),	    token(Rem, L, [space, Y |Result], Gen, BsNl)    end;%%---------------------------------------%% Command%%---------------------------------------token([$#|File], L, Result, not_set, BsNl) ->    {Rem, Command} = token_pp_com(File),    case catch list_to_integer(Command) of	{'EXIT', _} ->	    token(Rem, L, [{command,Command}|Result], not_set, BsNl);	_Int ->	    Result1 = [{number,Command}, {command,"line"}| Result],	    token(Rem, L, Result1, not_set, BsNl)    end;%%---------------------------------------%% Char%%---------------------------------------token([X|File], L, Result, Gen, BsNl) ->    GenNew = case Gen of not_set -> char; _ -> Gen end,    token(File, L, [{char,X}|Result], GenNew, BsNl).%%==================================================================%% Scan to the end of a token%%==================================================================%%---------------------------------------%% Number%%---------------------------------------tok_number([], Str) ->    {[], lists:reverse(Str)};tok_number([X|File], Str) when ?is_upper(X) ->    tok_number(File, [X|Str]);tok_number([X|File], Str) when ?is_lower(X) ->    tok_number(File, [X|Str]);tok_number([X|File], Str) when ?is_underline(X) ->    tok_number(File, [X|Str]);tok_number([X|File], Str) when ?is_number(X) ->    tok_number(File, [X|Str]);tok_number(File, Str) ->    {File, lists:reverse(Str)}.%%---------------------------------------%% Variable%%---------------------------------------tok_var([], Str) ->    {[], lists:reverse(Str)};tok_var([X|File], Str) when ?is_upper(X) ->    tok_var(File, [X|Str]);tok_var([X|File], Str) when ?is_lower(X) ->    tok_var(File, [X|Str]);tok_var([X|File], Str) when ?is_underline(X) ->    tok_var(File, [X|Str]);tok_var([X|File], Str) when ?is_number(X) ->    tok_var(File, [X|Str]);tok_var(File, Str) ->    {File, lists:reverse(Str)}.%%---------------------------------------%% Preprocessor command%%---------------------------------------token_pp_com([X|File]) when ?is_upper(X) ->    tok_var(File, [X]);token_pp_com([X|File]) when ?is_lower(X) ->    tok_var(File, [X]);token_pp_com([X|File]) when ?is_underline(X) ->    tok_var(File, [X]);token_pp_com([X|File]) when ?is_number(X) ->    tok_var(File, [X]);token_pp_com(File) ->    Rem = remove_leading_spaces(File),    {Rem, "null"}.%%---------------------------------------%% Comment%%---------------------------------------token_comment([]) ->    [];token_comment([$*,$/|File]) ->    File;token_comment([$\n|File]) ->    {[$/,$*|File], nl};token_comment([$\r,$\n|File]) ->    {[$/,$*|File], nl};token_comment([$\\,$\n|File]) ->    {[$/,$*|File], nl};%token_comment([$\\,$\n|File]) ->%    token_comment(File);token_comment([_|File]) ->    token_comment(File).%%---------------------------------------%% String%%---------------------------------------token_string([], Str) ->    {[], lists:reverse(Str)};token_string([$"|File], Str) ->    {File, lists:reverse(Str)};token_string([$\n|File], Str) ->    {File, lists:reverse(Str), nl};token_string([$\r,$\n|File], Str) ->    {File, lists:reverse(Str), nl};token_string([$\\,$\n|File], Str) ->    token_string(File, Str);token_string([X|File], Str) ->    token_string(File, [X|Str]).%%---------------------------------------%% Include%%---------------------------------------token_include([], Str) ->    {[], lists:reverse(Str)};token_include([$>|File], Str) ->    {File, lists:reverse(Str)};token_include([$\n|File], Str) ->    {File, lists:reverse(Str), nl};token_include([$\r,$\n|File], Str) ->    {File, lists:reverse(Str), nl};token_include([$\\,$\n|File], Str) ->    token_include(File, Str);token_include([X|File], Str) ->    token_include(File, [X|Str]).%%===================================================================================%% detokenise a list of tokens, until next newline%%%% Output: a string%%===================================================================================detokenise(Tokens) ->    detokenise(Tokens, []).detokenise([], Result) ->    lists:flatten(Result);detokenise([space], Result) ->    lists:flatten(Result);detokenise([space_exp], Result) ->    lists:flatten(Result);detokenise([space|Rem], Result) ->    detokenise(Rem, Result++[?space]);detokenise([space_exp|Rem], Result) ->    detokenise(Rem, Result++[?space]);detokenise([nl|Rem], Result) ->    detokenise(Rem, Result++[$\n]);detokenise([{_, String}|Rem], Result) ->    detokenise(Rem, Result++[String]).detokenise_pragma(Tokens) ->    detokenise_pragma(Tokens, []).detokenise_pragma([], Result) ->    lists:flatten(Result);detokenise_pragma([space], Result) ->    lists:flatten(Result);detokenise_pragma([space|Rem], Result) ->    detokenise_pragma(Rem, Result++[?space]);detokenise_pragma([nl|Rem], Result) ->    detokenise_pragma(Rem, Result++[$\n]);detokenise_pragma([{string, String}|Rem], Result) ->    detokenise_pragma(Rem, Result++[$"|String]++[$"]);detokenise_pragma([{_, String}|Rem], Result) ->    detokenise_pragma(Rem, Result++[String]).%%======================================================================================%%======================================================================================%%======================================================================================%% Expand macros.%%%%%% Output:  A text file%%%% Description: Expands all macros. All macro definitions are logged in a list 'Defs'%%              and all found errors and warnings are logged in a list 'Err' and 'War',%%              respectively.%%%%              When a macro name is found in a source line it is expanded according%%              to the current 'Defs'-list. The macro must agree both to the name%%              and number of parameters, otherwise an error is reported.%%======================================================================================%%======================================================================================%%====================================================================================== expand(List, FileName, IncDir, Flags) ->    %% Get all definitions from preprocessor commnads    %% and merge them on top of the file collected.    CLDefs = get_cmd_line_defs(Flags),    expand(List, [], [], CLDefs, [FileName], IncDir, check_all, [], [], 1, FileName).expand(List, Defs, Err, War, [FileName|IncFile], IncDir) ->    expand(List, [], [], Defs, [FileName|IncFile], IncDir, check_all, Err, War, 1, FileName).%%=======================================================%% Main loop for the expansion%%=======================================================expand([], Out, _SelfRef, Defs, _IncFile, _IncDir, IfCou, Err, War, _L, _FN) ->%    io:format("~n   ===============~n"),%    io:format("   definitions    ~p~n",[lists:reverse(Defs)]),%    io:format("   found warnings ~p~n",[lists:reverse(War)]),%    io:format("   found errors   ~p~n",[lists:reverse(Err)]),%    io:format("   ===============~n~n~n"),    {Out, Err, War, Defs, IfCou};expand([{file_info, 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);%%---------------------------------------%% Searching for endif, %% i.e skip all source lines until matching%% end if is encountered%%---------------------------------------expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN)   when Command == "ifdef" ->    {_Removed, Rem2, _Nl} = read_to_nl(Rem),    IfCou2 = {endif, Endif+1, IfLine},    expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err, War, L, FN);expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN)  when Command == "ifndef" ->    {_Removed, Rem2, _Nl} = read_to_nl(Rem),    IfCou2 = {endif, Endif+1, IfLine},    expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err, War, L, FN);expand([{command,Command} | Rem], Out, SelfRef, Defs, IncFile, IncDir, {endif, Endif, IfLine}, Err, War, L, FN)  when Command == "if" ->    case pp_command(Command, Rem, Defs, IncDir, Err, War, L, FN) of        {{'if', true}, Rem2, Err2, War2, Nl} ->            IfCou2 = {endif, Endif+1, IfLine},            expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err2, War2, L+Nl, FN);%%        {{'if', false}, Rem2, Err2, War2, Nl} -> Not implemented yet        {{'if', error}, Rem2, Err2, War2, Nl} ->            IfCou2 = {endif, Endif, IfLine},            expand(Rem2, Out, SelfRef, Defs, IncFile, IncDir, IfCou2, Err2, War2, L+Nl, FN)

⌨️ 快捷键说明

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