Navigation Menu

Skip to content

Commit

Permalink
Fix compilation of mime_types.erl when working directory is not 'yaws'
Browse files Browse the repository at this point in the history
When mime_types.erl is generated, we must check if it is done during a Yaws
compilation or a Yaws startup. In the first case, we must use a relative
path for includes. Else include_lib must be used.
This issue was reported by Andrei Zavada and avoid a compile error when the
working directory is not 'yaws'.

The mechanisms to generate and compile this file have also changed.

Then, to centralize calls to yaws_generated:is_local_install/0, following
functions was added in yaws.erl:
  get_app_dir/0, get_src_dir/0, get_ebin_dir/0, get_priv_dir/0, get_inc_dir/0
  • Loading branch information
Christopher Faulet committed Nov 29, 2012
1 parent dc424c8 commit 7061375
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 103 deletions.
1 change: 1 addition & 0 deletions configure.in
Expand Up @@ -333,6 +333,7 @@ AC_SUBST(HAVE_YAWS_SENDFILE)
YTOP=`pwd`
AC_SUBST(YTOP)
AC_OUTPUT(include.mk)
AC_OUTPUT(priv/charset.def)
AC_OUTPUT(test/support/include.mk)
AC_OUTPUT(test/support/include.sh)

Expand Down
9 changes: 5 additions & 4 deletions known_dialyzer_warnings
@@ -1,8 +1,9 @@

yaws.erl:1657: The pattern 'false' can never match the type 'true'
yaws.erl:2144: Guard test Ret::'file' == 'fd' can never succeed
yaws.erl:2152: Guard test Ret::'file' == 'binfd' can never succeed
yaws_config.erl:548: The pattern 'false' can never match the type 'true'
mime_type_c.erl:69: The variable _ can never match since previous clauses completely covered the type 'true'
yaws.erl:2138: Guard test Ret::'file' == 'fd' can never succeed
yaws.erl:2146: Guard test Ret::'file' == 'binfd' can never succeed
yaws.erl:2377: The pattern 'false' can never match the type 'true'
yaws.erl:2384: The pattern 'false' can never match the type 'true'
yaws_ctl.erl:530: Function hup/1 has no local return
yaws_ctl.erl:535: Function stop/1 has no local return
yaws_ctl.erl:539: Function status/1 has no local return
Expand Down
1 change: 1 addition & 0 deletions priv/charset.def.in
@@ -0,0 +1 @@
@DEFAULT_CHARSET@
24 changes: 11 additions & 13 deletions scripts/rebar-pre-script
Expand Up @@ -34,22 +34,10 @@ keep_or_replace() {
cd src || fail

if [ "$1" = clean ]; then
rm -f mime_types.erl ../priv/charset.def yaws_configure.hrl yaws_generated.erl
rm -f mime_types.erl yaws_configure.hrl yaws_generated.erl
exit 0
fi

CHARSET=${DEFAULT_CHARSET-""}
need_mime=yes
if [ -f mime_types.erl ]; then
need_mime=`find mime_type_c.erl -newer mime_types.erl -print`
fi
if [ -n "$need_mime" ]; then
echo ${CHARSET} > ../priv/charset.def || fail
erlc -o ../ebin mime_type_c.erl || fail ../priv/charset.def
erl -pa ../ebin -noshell -s mime_type_c generate || \
fail ../priv/charset.def mime_types.erl
fi

if [ ! -f yaws_configure.hrl ]; then
echo '%% rebar sets HAVE_YAWS_SENDFILE in erlc command line' \
> yaws_configure.hrl
Expand All @@ -62,6 +50,16 @@ keep_or_replace yaws_generated.erl $tmpgen
[ -d "$YAWS_VARDIR" ] || mkdir "$YAWS_VARDIR" || fail
[ -d "$YAWS_ETCDIR" ] || mkdir "$YAWS_ETCDIR" || fail

need_mime=yes
if [ -f mime_types.erl ]; then
need_mime=`find mime_type_c.erl -newer mime_types.erl -print`
fi
if [ -n "$need_mime" ]; then
erlc -o ../ebin yaws_generated.erl || fail
erlc -o ../ebin mime_type_c.erl || fail
erl -pa ../ebin -noshell -s mime_type_c generate || fail mime_types.erl
fi

cd ../scripts

tmpgen=`mktemp /tmp/${script}.XXXXXX` || fail
Expand Down
37 changes: 16 additions & 21 deletions src/Makefile
Expand Up @@ -69,7 +69,6 @@ ERLC_FLAGS+=-Werror $(DEBUG_FLAGS) -pa ../../yaws -I ../include
#
# Targets
#

all: yaws_generated.erl yaws_configure.hrl $(EBIN_FILES)

dav:
Expand All @@ -80,39 +79,26 @@ $(EBIN_FILES) : ../include/yaws.hrl ../include/yaws_api.hrl
../ebin/yaws_sendfile.$(EMULATOR): yaws_configure.hrl

yaws_generated.erl: yaws_generated.template ../vsn.mk
. ../vsn.mk ; \
YAWS_VSN='$(YAWS_VSN)' VARDIR='$(VARDIR)' ETCDIR='$(ETCDIR)' \
../scripts/gen-yaws-generated true > yaws_generated.erl
$(MAKE) IS_LOCAL_INSTALL=true gen_yaws_generated

yaws_configure.hrl: ../vsn.mk ../include.mk
if [ $(HAVE_YAWS_SENDFILE) = "true" ]; then \
echo "-define(HAVE_YAWS_SENDFILE, true)." > yaws_configure.hrl; \
else touch yaws_configure.hrl; fi


## need to differentiate between local install and not
.PHONY: regen
regen:
. ../vsn.mk ; \
YAWS_VSN='$(YAWS_VSN)' VARDIR='$(VARDIR)' ETCDIR='$(ETCDIR)' \
../scripts/gen-yaws-generated false > yaws_generated.erl

charset.def:
if [ -n "$(DEFAULT_CHARSET)" ]; then \
echo $(DEFAULT_CHARSET) > ../priv/charset.def; \
else rm -f ../priv/charset.def ; touch ../priv/charset.def; fi

mime_types.erl: charset.def ../ebin/mime_type_c.beam
mime_types.erl: ../priv/charset.def ../priv/mime.types \
../ebin/yaws_generated.$(EMULATOR) ../ebin/mime_type_c.$(EMULATOR)
$(ERL) -noshell -pa ../ebin -s mime_type_c generate


debug:
$(MAKE) TYPE=debug

clean:
rm -f $(EBIN_FILES) yaws_generated.erl yaws_configure.hrl \
mime_types.erl ../priv/charset.def
rm -f $(EBIN_FILES) yaws_generated.erl yaws_configure.hrl mime_types.erl

install: regen all docsinstall
install: all docsinstall
$(MAKE) IS_LOCAL_INSTALL=false gen_yaws_generated
$(INSTALL) -d $(DESTDIR)$(LIBDIR)/yaws/examples/ebin
$(INSTALL) -d $(DESTDIR)$(LIBDIR)/yaws/examples/include
$(INSTALL) -d $(DESTDIR)$(LIBDIR)/yaws/ebin
Expand All @@ -123,6 +109,7 @@ install: regen all docsinstall
(cd ..; tar cf - include ) | (cd $(DESTDIR)$(LIBDIR)/yaws; tar xf - )
(cd ..; tar cf - priv/*.xsd ) | (cd $(DESTDIR)$(LIBDIR)/yaws; tar xf - )
$(INSTALL) -m 644 ../priv/mime.types $(DESTDIR)$(LIBDIR)/yaws/priv
$(MAKE) IS_LOCAL_INSTALL=true gen_yaws_generated

docsinstall:
$(INSTALL) -d $(DESTDIR)$(VARDIR)/yaws/www
Expand All @@ -135,3 +122,11 @@ xref:
erl -noshell -pa ../ebin -s yaws_debug xref ../ebin



## need to differentiate between local install and not
gen_yaws_generated:
rm -f yaws_generated.erl ../ebin/yaws_generated.$(EMULATOR)
YAWS_VSN='$(YAWS_VSN)' VARDIR='$(VARDIR)' ETCDIR='$(ETCDIR)' \
../scripts/gen-yaws-generated $(IS_LOCAL_INSTALL) > yaws_generated.erl
$(MAKE) ../ebin/yaws_generated.$(EMULATOR)

29 changes: 23 additions & 6 deletions src/mime_type_c.erl
Expand Up @@ -13,7 +13,7 @@
-include("../include/yaws.hrl").


-define(MIME_TYPES_FILE, filename:join(code:priv_dir(yaws), "mime.types")).
-define(MIME_TYPES_FILE, filename:join(yaws:get_priv_dir(), "mime.types")).
-define(DEFAULT_MIME_TYPE, "text/plain").

%% This function is used during Yaws' compilation. To rebuild/reload mime_types
Expand All @@ -25,13 +25,14 @@ generate() ->
SrcDir = filename:dirname(
proplists:get_value(source, ?MODULE:module_info(compile))
),
PrivDir = filename:join(filename:dirname(SrcDir), "priv"),
Charset = read_charset_file(filename:join(PrivDir, "charset.def")),
EbinDir = filename:dirname(code:which(?MODULE)),
Charset = read_charset_file(filename:join(EbinDir, "../priv/charset.def")),
GInfo = #mime_types_info{
mime_types_file = filename:join(PrivDir, "mime.types"),
mime_types_file = filename:join(SrcDir, "../priv/mime.types"),
default_charset = Charset
},
ModFile = filename:join(SrcDir, "mime_types.erl"),

case generate(ModFile, GInfo, []) of
ok ->
erlang:halt(0);
Expand All @@ -52,12 +53,29 @@ generate(ModFile, GInfo, SInfoMap) ->
{Name, Info} <- [{global, GInfo}|SInfoMap] ],

%% Generate module Header
%%
%% We must make the difference between generation during Yaws
%% compilation and generation during Yaws startup.
%% below, ignore dialyzer warning:
%% "The pattern 'false' can never match the type 'true'"
Inc = case yaws_generated:is_local_install() of
true ->
Info = ?MODULE:module_info(compile),
SrcDir = filename:dirname(
proplists:get_value(source, Info)
),
F = filename:join([SrcDir, "../include/yaws.hrl"]),
"-include(\""++F++"\").";
_ ->
"-include_lib(\"yaws/include/yaws.hrl\")."
end,
io:format(Fd,
"-module(mime_types).~n~n"
"-export([default_type/0, default_type/1]).~n"
"-export([t/1, revt/1]).~n"
"-export([t/2, revt/2]).~n~n"
"-include_lib(\"yaws/include/yaws.hrl\").~n~n", []),
"~s~n~n", [Inc]),


%% Generate default_type/0, t/1 and revt/1
io:format(Fd,
Expand Down Expand Up @@ -258,4 +276,3 @@ get_ext_type("cgi") -> cgi;
get_ext_type("fcgi") -> fcgi;
get_ext_type(_) -> regular.


48 changes: 38 additions & 10 deletions src/yaws.erl
Expand Up @@ -100,6 +100,9 @@

-export([parse_ipmask/1, match_ipmask/2]).

-export([get_app_dir/0, get_ebin_dir/0, get_priv_dir/0,
get_inc_dir/0, get_src_dir/0]).

%% Internal
-export([local_time_as_gmt_string/1, universal_time_as_string/1,
stringdate_to_datetime/1]).
Expand Down Expand Up @@ -1649,16 +1652,7 @@ uid_to_name(Uid) ->
end.

load_setuid_drv() ->
%% below, ignore dialyzer warning:
%% "The pattern 'false' can never match the type 'true'"
Path = case yaws_generated:is_local_install() of
true ->
filename:dirname(code:which(?MODULE)) ++ "/../priv/lib";
false ->
%% ignore dialyzer on this one
PrivDir = code:priv_dir(yaws),
filename:join(PrivDir,"lib")
end,
Path = filename:join(get_priv_dir(), "lib"),
case erl_ddll:load_driver(Path, "setuid_drv") of
ok ->
ok;
Expand Down Expand Up @@ -2370,3 +2364,37 @@ compare_ips({A,B1,_,_,_,_,_,_}, {A,B2,_,_,_,_,_,_}) when B1 > B2 -> greater;
compare_ips({A1,_,_,_,_,_,_,_}, {A2,_,_,_,_,_,_,_}) when A1 < A2 -> less;
compare_ips({A1,_,_,_,_,_,_,_}, {A2,_,_,_,_,_,_,_}) when A1 > A2 -> greater;
compare_ips(_, _) -> error.


%% ----
get_app_subdir(SubDir) when is_atom(SubDir) ->
%% below, ignore dialyzer warning:
%% "The pattern 'false' can never match the type 'true'"
case yaws_generated:is_local_install() of
true ->
EbinDir = get_ebin_dir(),
filename:join(filename:dirname(EbinDir), atom_to_list(SubDir));
false ->
code:lib_dir(yaws, SubDir)
end.

get_app_dir() ->
%% below, ignore dialyzer warning:
%% "The pattern 'false' can never match the type 'true'"
case yaws_generated:is_local_install() of
true -> filename:dirname(get_ebin_dir());
false -> code:lib_dir(yaws)
end.

get_src_dir() ->
Info = ?MODULE:module_info(compile),
filename:dirname(proplists:get_value(source, Info)).

get_ebin_dir() ->
filename:dirname(code:which(?MODULE)).

get_priv_dir() ->
get_app_subdir(priv).

get_inc_dir() ->
get_app_subdir(include).
30 changes: 1 addition & 29 deletions src/yaws_config.erl
Expand Up @@ -538,35 +538,7 @@ make_default_sconf(DocRoot, Port) ->


yaws_dir() ->
%% below, ignore dialyzer warning:
%% "The pattern 'false' can never match the type 'true'"
case yaws_generated:is_local_install() of
true ->
P = filename:split(code:which(?MODULE)),
P1 = del_tail(P),
filename:join(P1);
false ->
code:lib_dir(yaws)
end.

del_tail(Parts) ->
del_tail(Parts,[]).
%% Initial ".." should be preserved
del_tail([".." |Tail], Acc) ->
del_tail(Tail, [".."|Acc]);
del_tail(Parts, Acc) ->
del_tail2(Parts, Acc).

%% Embedded ".." should be removed together with preceding dir
del_tail2([_H, ".." |Tail], Acc) ->
del_tail2(Tail, Acc);
del_tail2([".." |Tail], [_P|Acc]) ->
del_tail2(Tail, Acc);
del_tail2([_X, _Y], Acc) ->
lists:reverse(Acc);
del_tail2([H|T], Acc) ->
del_tail2(T, [H|Acc]).

yaws:get_app_dir().

string_to_host_and_port(String) ->
case string:tokens(String, ":") of
Expand Down
9 changes: 1 addition & 8 deletions src/yaws_sendfile.erl
Expand Up @@ -110,14 +110,7 @@ stop() ->
init([]) ->
process_flag(trap_exit, true),
Shlib = "yaws_sendfile_drv",
Dir = case yaws_generated:is_local_install() of
true ->
filename:dirname(code:which(?MODULE)) ++ "/../priv/lib";
false ->
%% ignore dialyzer on this one
PrivDir = code:priv_dir(yaws),
filename:join(PrivDir,"lib")
end,
Dir = filename:join(yaws:get_priv_dir(), "lib"),
case erl_ddll:load_driver(Dir, Shlib) of
ok -> ok;
{error, already_loaded} -> ok;
Expand Down
7 changes: 1 addition & 6 deletions src/yaws_soap12_lib.erl
Expand Up @@ -347,12 +347,7 @@ initModelFile(ConfigFile) ->
initModel2(WsdlFile, [{prefix, Prefix}], XsdPath, Import, AddFiles).

priv_dir() ->
case code:priv_dir(yaws) of
{error, bad_name} ->
filename:join([filename:dirname(code:which(yaws)),"..", "priv"]);
A ->
A
end.
yaws:get_priv_dir().

initModel2(WsdlFile, ErlsomOptions, Path, Import, AddFiles) ->
WsdlName = filename:join([Path, "wsdl.xsd"]),
Expand Down
7 changes: 1 addition & 6 deletions src/yaws_soap_lib.erl
Expand Up @@ -307,12 +307,7 @@ initModelFile(ConfigFile) ->
initModel2(WsdlFile, [{prefix, Prefix}], XsdPath, Import, AddFiles).

priv_dir() ->
case code:priv_dir(yaws) of
{error, bad_name} ->
filename:join([filename:dirname(code:which(yaws)),"..", "priv"]);
A ->
A
end.
yaws:get_priv_dir().

initModel2(WsdlFile, ErlsomOptions, Path, Import, AddFiles) ->
WsdlName = filename:join([Path, "wsdl.xsd"]),
Expand Down

0 comments on commit 7061375

Please sign in to comment.