Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
2813-parsetools-Let-Leex-recognize-ERL_COMPILER...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 2813-parsetools-Let-Leex-recognize-ERL_COMPILER_OPTIONS.patch of Package erlang
From 31a7aeed186bd6c2113e7d9b5b59d996be4629a3 Mon Sep 17 00:00:00 2001 From: Hans Bolinder <hasse@erlang.org> Date: Tue, 24 Nov 2020 09:24:24 +0100 Subject: [PATCH 3/3] parsetools: Let Leex recognize ERL_COMPILER_OPTIONS --- lib/parsetools/doc/src/leex.xml | 16 +++ lib/parsetools/src/leex.erl | 161 +++++++++++++++++------------ lib/parsetools/test/leex_SUITE.erl | 31 +++++- 3 files changed, 142 insertions(+), 66 deletions(-) diff --git a/lib/parsetools/doc/src/leex.xml b/lib/parsetools/doc/src/leex.xml index 0e69e44667..153374e16a 100644 --- a/lib/parsetools/doc/src/leex.xml +++ b/lib/parsetools/doc/src/leex.xml @@ -241,6 +241,22 @@ io:request(InFile, {get_until,unicode,Prompt,Module,tokens,[Line]}) </func> </funcs> + <section> + <title>Default Leex Options</title> + <p>The (host operating system) environment variable + <c>ERL_COMPILER_OPTIONS</c> can be used to give default Leex + options. Its value must be a valid Erlang term. If the value is a + list, it is used as is. If it is not a list, it is put + into a list.</p> + + <p>The list is appended to any options given to + <seemfa marker="#file/2">file/2</seemfa>.</p> + + <p>The list can be retrieved with + <seemfa marker="compiler:compile#env_compiler_options/0"> + compile:env_compiler_options/0</seemfa>.</p> + </section> + <section> <title>Input File Format</title> <p>Erlang style comments starting with a <c>%</c> are allowed in diff --git a/lib/parsetools/src/leex.erl b/lib/parsetools/src/leex.erl index f60ad76175..90d1b9f71e 100644 --- a/lib/parsetools/src/leex.erl +++ b/lib/parsetools/src/leex.erl @@ -34,9 +34,8 @@ -export([compile/3,file/1,file/2,format_error/1]). --import(lists, [member/2,reverse/1,sort/1,delete/2, - keysort/2,keydelete/3, - map/2,foldl/3,foreach/2,flatmap/2]). +-import(lists, [member/2,reverse/1,sort/1,keysort/2, + map/2,foldl/3,foldr/3,foreach/2,flatmap/2]). -import(ordsets, [is_element/2,add_element/2,union/2]). -import(orddict, [store/3]). @@ -123,12 +122,15 @@ file(File) -> file(File, []). | 'return_errors' | 'return_warnings' | 'return' | 'verbose' | 'warnings_as_errors'. -file(File, Opts0) -> +file(File, Opts0) when is_list(Opts0) -> case is_filename(File) of no -> erlang:error(badarg, [File,Opts0]); _ -> ok end, - Opts = case options(Opts0) of + EnvOpts0 = env_default_opts(), + EnvOpts = select_recognized_opts(EnvOpts0), + Opts1 = Opts0 ++ EnvOpts, + Opts = case options(Opts1) of badarg -> erlang:error(badarg, [File,Opts0]); Options -> @@ -152,7 +154,9 @@ file(File, Opts0) -> catch #leex{}=St4 -> St4 end, - leex_ret(St). + leex_ret(St); +file(File, Opt) -> + file(File, [Opt]). -spec format_error(ErrorDescriptor) -> io_lib:chars() when ErrorDescriptor :: term(). @@ -196,83 +200,112 @@ strip_extension(File, Ext) -> _Other -> File end. -options(Options0) when is_list(Options0) -> - try - Options = flatmap(fun(return) -> short_option(return, true); - (report) -> short_option(report, true); - ({return,T}) -> short_option(return, T); - ({report,T}) -> short_option(report, T); - (T) -> [T] - end, Options0), - options(Options, [scannerfile,includefile,report_errors, - report_warnings,warnings_as_errors, - return_errors,return_warnings, - verbose,dfa_graph], []) - catch error: _ -> badarg - end; -options(Option) -> - options([Option]). - -short_option(return, T) -> - [{return_errors,T}, {return_warnings,T}]; -short_option(report, T) -> - [{report_errors,T}, {report_warnings,T}]. - -options(Options0, [Key|Keys], L) when is_list(Options0) -> - Options = case member(Key, Options0) of - true -> - [atom_option(Key)|delete(Key, Options0)]; - false -> - Options0 - end, - V = case lists:keyfind(Key, 1, Options) of - {Key, Filename0} when Key =:= includefile; - Key =:= scannerfile -> - case is_filename(Filename0) of - no -> - badarg; - Filename -> - {ok,[{Key,Filename}]} - end; - {Key, Bool} = KB when is_boolean(Bool) -> - {ok, [KB]}; - {Key, _} -> - badarg; - false -> - {ok,[{Key,default_option(Key)}]} - end, - case V of +%% Copied from compile.erl. +env_default_opts() -> + Key = "ERL_COMPILER_OPTIONS", + case os:getenv(Key) of + false -> []; + Str when is_list(Str) -> + case erl_scan:string(Str) of + {ok,Tokens,_} -> + Dot = {dot, erl_anno:new(1)}, + case erl_parse:parse_term(Tokens ++ [Dot]) of + {ok,List} when is_list(List) -> List; + {ok,Term} -> [Term]; + {error,_Reason} -> + io:format("Ignoring bad term in ~s\n", [Key]), + [] + end; + {error, {_,_,_Reason}, _} -> + io:format("Ignoring bad term in ~s\n", [Key]), + [] + end + end. + +select_recognized_opts(Options0) -> + Options = preprocess_options(Options0), + AllOptions = all_options(), + [Option || + {Name, _} = Option <- Options, + lists:member(Name, AllOptions)]. + +options(Options0) -> + Options1 = preprocess_options(Options0), + AllOptions = all_options(), + case check_options(Options1, AllOptions, []) of badarg -> badarg; - {ok,KeyValueL} -> - NewOptions = keydelete(Key, 1, Options), - options(NewOptions, Keys, KeyValueL ++ L) + OptionValues -> + AllOptionValues = + [case lists:keyfind(Option, 1, OptionValues) of + false -> + {Option, default_option(Option)}; + OptionValue -> + OptionValue + end || Option <- AllOptions], + foldr(fun({_, false}, L) -> L; + ({Option, true}, L) -> [Option | L]; + (OptionValue, L) -> [OptionValue | L] + end, [], AllOptionValues) + end. + +preprocess_options(Options) -> + foldr(fun preproc_opt/2, [], Options). + +preproc_opt(return, Os) -> + [{return_errors, true}, {return_warnings, true} | Os]; +preproc_opt(report, Os) -> + [{report_errors, true}, {report_warnings, true} | Os]; +preproc_opt({return, T}, Os) -> + [{return_errors, T}, {return_warnings, T} | Os]; +preproc_opt({report, T}, Os) -> + [{report_errors, T}, {report_warnings, T} | Os]; +preproc_opt(Option, Os) -> + [try atom_option(Option) catch error:_ -> Option end | Os]. + +check_options([{Option, FileName0} | Options], AllOptions, L) + when Option =:= includefile; Option =:= scannerfile -> + case is_filename(FileName0) of + no -> + badarg; + Filename -> + check_options(Options, AllOptions, [{Option, Filename} | L]) end; -options([], [], L) -> - foldl(fun({_,false}, A) -> A; - ({Tag,true}, A) -> [Tag|A]; - (F,A) -> [F|A] - end, [], L); -options(_Options, _, _L) -> +check_options([{Option, Boolean} | Options], AllOptions, L) + when is_boolean(Boolean) -> + case lists:member(Option, AllOptions) of + true -> + check_options(Options, AllOptions, [{Option, Boolean} | L]); + false -> + badarg + end; +check_options([], _AllOptions, L) -> + L; +check_options(_Options, _, _L) -> badarg. +all_options() -> + [dfa_graph,includefile,report_errors,report_warnings, + return_errors,return_warnings,scannerfile,verbose, + warnings_as_errors]. + default_option(dfa_graph) -> false; default_option(includefile) -> []; default_option(report_errors) -> true; default_option(report_warnings) -> true; -default_option(warnings_as_errors) -> false; default_option(return_errors) -> false; default_option(return_warnings) -> false; default_option(scannerfile) -> []; -default_option(verbose) -> false. +default_option(verbose) -> false; +default_option(warnings_as_errors) -> false. atom_option(dfa_graph) -> {dfa_graph,true}; atom_option(report_errors) -> {report_errors,true}; atom_option(report_warnings) -> {report_warnings,true}; atom_option(warnings_as_errors) -> {warnings_as_errors,true}; atom_option(return_errors) -> {return_errors,true}; -atom_option(return_warnings) -> {return_warnings,true}; atom_option(verbose) -> {verbose,true}; +atom_option(return_warnings) -> {return_warnings,true}; atom_option(Key) -> Key. is_filename(T) -> diff --git a/lib/parsetools/test/leex_SUITE.erl b/lib/parsetools/test/leex_SUITE.erl index 16f67f7f26..e8ec376d4b 100644 --- a/lib/parsetools/test/leex_SUITE.erl +++ b/lib/parsetools/test/leex_SUITE.erl @@ -45,7 +44,7 @@ pt/1, man/1, ex/1, ex2/1, not_yet/1, line_wrap/1, otp_10302/1, otp_11286/1, unicode/1, otp_13916/1, otp_14285/1, - compiler_warnings/1]). + otp_17023/1, compiler_warnings/1]). % Default timetrap timeout (set in init_per_testcase). -define(default_timeout, ?t:minutes(1)). @@ -67,7 +67,7 @@ all() -> groups() -> [{checks, [], [file, compile, syntax]}, {examples, [], [pt, man, ex, ex2, not_yet, unicode]}, - {tickets, [], [otp_10302, otp_11286, otp_13916, otp_14285, + {tickets, [], [otp_10302, otp_11286, otp_13916, otp_14285, otp_17023, compiler_warnings]}, {bugs, [], [line_wrap]}]. @@ -1185,6 +1185,32 @@ otp_14285(Config) -> {ok, compiler_warnings, []} = compile:file(ErlFile, [return]), ok. +otp_17023(Config) -> + Dir = ?privdir, + Filename = filename:join(Dir, "file.xrl"), + Ret = [return, {report, true}], + + {'EXIT', {badarg, _}} = (catch leex:file(Filename, [{noopt,true}])), + OldEnv = os:getenv("ERL_COMPILER_OPTIONS"), + true = os:putenv("ERL_COMPILER_OPTIONS", "strong_validation"), + ok = file:write_file(Filename, + <<"Definitions.\n" + "Rules.\n" + "^ : .\n" + "Erlang code.\n">>), + {error,[{_,[{3,leex,{regexp,_}}]}],[]} = + leex:file(Filename, Ret), + true = os:putenv("ERL_COMPILER_OPTIONS", "{return, false}"), + error = leex:file(Filename, Ret), + error = leex:file(Filename, [return | Ret]), % overridden + case OldEnv of + false -> + os:unsetenv("ERL_COMPILER_OPTIONS"); + _ -> + os:putenv("ERL_COMPILER_OPTIONS", OldEnv) + end, + ok. + start_node(Name, Args) -> [_,Host] = string:tokens(atom_to_list(node()), "@"), ct:log("Trying to start ~w@~s~n", [Name,Host]), -- 2.26.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor