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