ic_pp.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,740 行 · 第 1/5 页
ERL
1,740 行
case is_define_ok(Name, No_of_para, Parameters, Macro, Defs) of {yes, Defs2} -> {define, Rem, Defs2, Err2, War2, Nl}; {no, Defs2} -> Text = lists:flatten(io_lib:format("`~s' redefined",[Name])), {define, Rem, Defs2, Err2, [{FN, L, Text}|War2], Nl}; {error, Text, Defs2} -> {define, Rem, Defs2, [{FN, L, Text}|Err2], War2, Nl} end; {ok, Rem, Name, No_of_para, Parameters, Macro, Err2, War2, Nl} -> case is_define_ok(Name, No_of_para, Parameters, Macro, Defs) of {yes, Defs2} -> {define, Rem, Defs2, Err2, War2, Nl}; {no, Defs2} -> Text = lists:flatten(io_lib:format("`~s' redefined",[Name])), {define, Rem, Defs2, Err2, [{FN, L, Text}|War2], Nl}; {error, Text, Defs2} -> {define, Rem, Defs2, [{FN, L, Text}|Err2], War2, Nl} end end; %%---------------------------------------- %% #undef %%---------------------------------------- "undef" -> case undef(File, Err, War, L, FN) of {error, Rem, Err2, War2, Nl} -> {undef, Rem, Defs, Err2, War2, Nl}; {ok, Rem, Name, Err2, War2, Nl} -> Defs2 = lists:keydelete(Name, 1, Defs), {undef, Rem, Defs2, Err2, War2, Nl} end; %%---------------------------------------- %% #include %%---------------------------------------- "include" -> case include(File, IncDir) of {error, Rem, Nl, Err2} -> {{include, error}, Rem, Nl, [{FN, L, Err2}|Err], War}; {error, Rem, Nl, Err2, NameNl} -> {{include, error}, Rem, Nl, [{FN, L+ NameNl, Err2}|Err], War}; {ok, FileName, FileCont, Rem, Nl} -> {{include, ok}, FileName, FileCont, Rem, Nl, Err, War} end; %%---------------------------------------- %% #ifdef %%---------------------------------------- "ifdef" -> case define(File, Err, War, L, FN) of {error, Rem, Err2, War2, Nl} -> {{ifdef, false}, Rem, Defs, Err2, War2, Nl}; {warning, Rem, Name, No_of_para, _Parameters, _Macro, Err2, War2, Nl} -> case is_defined_before(Name, No_of_para, Defs) of yes -> {{ifdef, false}, Rem, Err2, War2, Nl}; no -> {{ifdef, true}, Rem, Err2, War2, Nl} end; {ok, Rem, Name, No_of_para, _Parameters, _Macro, Err2, War2, Nl} -> case is_defined_before(Name, No_of_para, Defs) of yes -> {{ifdef, false}, Rem, Err2, War2, Nl}; no -> {{ifdef, true}, Rem, Err2, War2, Nl} end end; %%---------------------------------------- %% #ifndef %%---------------------------------------- "ifndef" -> case define(File, Err, War, L, FN) of {error, Rem, Err2, War2, Nl} -> {{ifndef, false}, Rem, Defs, Err2, War2, Nl}; {warning, Rem, Name, No_of_para, _Parameters, _Macro, Err2, War2, Nl} -> case is_defined_before(Name, No_of_para, Defs) of yes -> {{ifndef, true}, Rem, Err2, War2, Nl}; no -> {{ifndef, false}, Rem, Err2, War2, Nl} end; {ok, Rem, Name, No_of_para, _Parameters, _Macro, Err2, War2, Nl} -> case is_defined_before(Name, No_of_para, Defs) of yes -> {{ifndef, true}, Rem, Err2, War2, Nl}; no -> {{ifndef, false}, Rem, Err2, War2, Nl} end end; %%---------------------------------------- %% #endif %%---------------------------------------- "endif" -> {Removed, Rem, Nl} = read_to_nl(File), case Removed of [] -> {endif, Rem, Err, War, 1}; _ -> Text = "ignoring the tail of the line", {ok, Rem, Err, [{FN, L, Text}|War], Nl} end; %%---------------------------------------- %% #if %%---------------------------------------- "if" -> case if_zero(File, Err, War, L, FN) of {error, Rem2, _Removed, Nl} -> Err2 = {FN, L, "only '#if 0' is implemented at present"}, {{'if', error}, Rem2, [Err2 | Err], War, Nl}; {ok, Rem2, 0, _Removed, Nl} -> {{'if', true}, Rem2, Err, War, Nl}; {ok, Rem2, _Num, _Removed, Nl} -> Err2 = {FN, L, "only '#if 0' is implemented at present"}, {{'if', error}, Rem2, [Err2 | Err], War, Nl} end; %%---------------------------------------- %% #else %%---------------------------------------- "else" -> {'else', read_to_nl(File)}; %%---------------------------------------- %% #elif %%---------------------------------------- "elif" -> {'elif', read_to_nl(File)}; %%---------------------------------------- %% #pragma %%---------------------------------------- "pragma" -> {Removed, Rem, Nl} = read_to_nl(File), {pragma, Rem, Nl, lists:reverse("#pragma " ++ detokenise_pragma(Removed))}; %%---------------------------------------- %% #ident %%---------------------------------------- "ident" -> {Removed, Rem, Nl} = read_to_nl(File), {ident, Rem, Nl, lists:reverse("#ident " ++ detokenise_pragma(Removed))}; %%---------------------------------------- %% #warning %%---------------------------------------- "warning" -> {warning, read_to_nl(File)}; %%---------------------------------------- %% #error %%---------------------------------------- "error" -> {error, read_to_nl(File)}; %%---------------------------------------- %% #line %%---------------------------------------- "line" -> line(File, L, FN); %%---------------------------------------- %% # %%---------------------------------------- "null" -> hash_mark; %%---------------------------------------- %% not recognised preprocessor commands %%---------------------------------------- _Else -> {not_recognised, read_to_nl(File)} end.%%===============================================================%%===============================================================%%===============================================================%% if%%%% Only #if 0 is implemented at the time to be able to use if%% to comment some code parts.%%===============================================================%%===============================================================%%===============================================================if_zero(File, _Err, _War, _L, _FN) -> case if_zero(File) of {ok, Remain, Num, Removed, Nl} -> case catch list_to_integer(Num) of {'EXIT', _} -> {Removed2, Rem2, Nl2} = read_to_nl(File), {error, Rem2, Removed2, Nl2}; Int -> {ok, Remain, Int, Removed, Nl} end; E -> E end.if_zero([{number,Num}]) -> {ok, [], Num, [], 0};if_zero([{number,Num}, space]) -> {ok, [], Num, [], 0};if_zero([{number,Num} | Rem]) -> {Removed, Rem2, Nl} = read_to_nl(Rem), {ok, Rem2, Num, Removed, Nl};%if_zero([{number,Num}, {nl,_X} | Rem]) ->% {ok, Rem, Num, [], 1};if_zero(Rem) -> {Removed, Rem2, Nl} = read_to_nl(Rem), {error, Rem2, Removed, Nl}.%%===============================================================%%===============================================================%%===============================================================%% Define macro%%%% Check the syntax of the macro, extract the parameters if any.%% If valid macro it is added to the Defs-list.%% If a macro is redefined, a warning will be given, the latest%% definition is always the valid one.%%===============================================================%%===============================================================%%===============================================================define(File, Err, War, L, FN) -> case define_name(File) of {ok, Rem, Name, No_of_para, Parameters, Macro, Nl} -> {ok, Rem, Name, No_of_para, Parameters, Macro, Err, War, Nl}; {{warning,no_space}, Rem, Name, No_of_para, Parameters, Macro, Nl} -> Text = lists:flatten(io_lib:format("missing white space after `#define ~s'",[Name])), {warning, Rem, Name, No_of_para, Parameters, Macro, Err, [{FN, L, Text}|War], Nl}; {error, invalid_name, Nl} -> Text = "invalid macro name", {_Removed, Rem, Nl2} = read_to_nl(File), {error, Rem, [{FN, L, Text}|Err], War, Nl+Nl2}; {error, invalid_name, Name, Nl} -> Text = lists:flatten(io_lib:format("invalid macro name `~s'",[Name])), {_Removed, Rem, Nl2} = read_to_nl(File), {error, Rem, [{FN, L, Text}|Err], War, Nl+Nl2}; {error, illegal_arg} -> {Removed, Rem, Nl} = read_to_nl(File), RemovedS = detokenise(Removed), Text = lists:flatten(io_lib:format("Invalid argument list ~s",[RemovedS])), {error, Rem, [{FN, L, Text}|Err], War, Nl} end.%%=========================================================== %% Check if valid macro %%=========================================================== define_name([]) -> {warning, no_macro};define_name([space]) -> {warning, no_macro};%% Macro with parametersdefine_name([{var,Name},{char,$(}|Rem]) -> case read_para([{char,$(}|Rem]) of {ok, Rem2, Para, NoOfPara} -> {Removed, Rem3, _Nl} = read_to_nl(Rem2), {ok, Rem3, Name, NoOfPara, Para, Removed, 1}; Error -> Error end;%% Macro without parametersdefine_name([{var,Name}]) -> {ok, [], Name, 0, [], [], 0};define_name([{var,Name}, space | Rem]) -> {Removed, Rem2, Nl} = read_to_nl(Rem), {ok, Rem2, Name, 0, [], Removed, Nl};define_name([{var,Name}, {nl,_X} | Rem]) -> {ok, Rem, Name, 0, [], [], 1};define_name([{var,Name} | Rem]) -> {Removed, Rem2, Nl} = read_to_nl(Rem), {{warning,no_space}, Rem2, Name, 0, [], Removed, Nl};%% Invalid macro namedefine_name([{number, Name} | _Rem]) -> {error, invalid_name, Name, 0};define_name(_Rem) -> {error, invalid_name, 0}.%%===============================================================%%===============================================================%%===============================================================%% Undefine macro%%%% If it is a valid undef command the macro name will be deleted%% from the Defs-list%%===============================================================%%===============================================================%%===============================================================undef(File, Err, War, L, FN) -> case undef(File) of {ok, Rem, Name, Nl} -> {ok, Rem, Name, Err, War, Nl}; {warning, Rem, Name, Nl} -> Text = "ignoring the tail of the line", {ok, Rem, Name, Err, [{FN, L, Text}|War], Nl}; {error, invalid_name} -> Text = "invalid macro name", {_Removed, Rem, Nl} = read_to_nl(File), {error, Rem, [{FN, L, Text}|Err], War, Nl}; {error, invalid_name, Name} -> Text = lists:flatten(io_lib:format("invalid macro name `~s'",[Name])), {_Removed, Rem, Nl} = read_to_nl(File), {error, Rem, [{FN, L, Text}|Err], War, Nl} end.%%------------------------------------------------- %% Check if valid macro name%%------------------------------------------------- undef([]) -> {error, invalid_name, []};%% Valid nameundef([{var,Name}]) -> {ok, [], Name, 0};undef([{var,Name}, {nl,_X} | Rem]) -> {ok, Rem, Name, 1};undef([{var,Name}, space, {nl,_X} | Rem]) -> {ok, Rem, Name, 1};undef([{var,Name} | Rem]) -> {_Removed, Rem2, Nl} = read_to_nl(Rem), {warning, Rem2, Name, Nl};%% Invalid macro nameundef([{number, Name} | _Rem]) -> {error, invalid_name, Name};undef(_Rem) -> {error, invalid_name}.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?