added debug build, fleshing out the tzdata parser. currently broken
This commit is contained in:
9
Makefile
9
Makefile
@@ -1,6 +1,8 @@
|
|||||||
ERLC_WARNINGS = -W1
|
ERLC_WARNINGS = -W1
|
||||||
MNESIA_DIR = db
|
MNESIA_DIR = db
|
||||||
RUN_INIT =
|
RUN_INIT =
|
||||||
|
DEBUG =
|
||||||
|
OPTIONS =
|
||||||
|
|
||||||
all : clean compile
|
all : clean compile
|
||||||
|
|
||||||
@@ -14,7 +16,7 @@ test : all
|
|||||||
erl -noshell -pa ebin -s test_master start -s erlang halt
|
erl -noshell -pa ebin -s test_master start -s erlang halt
|
||||||
|
|
||||||
compile :
|
compile :
|
||||||
erlc $(ERLC_WARNINGS) $(OPTIONS) -o ./ebin ./src/*.erl
|
erlc $(DEBUG) $(ERLC_WARNINGS) $(OPTIONS) -o ./ebin ./src/*.erl
|
||||||
-erl -noshell -pa ebin -s erldev make_app . -s erlang halt
|
-erl -noshell -pa ebin -s erldev make_app . -s erlang halt
|
||||||
|
|
||||||
clean :
|
clean :
|
||||||
@@ -23,3 +25,8 @@ clean :
|
|||||||
|
|
||||||
run :
|
run :
|
||||||
erl -pa ebin -mnesia dir $(MNESIA_DIR) $(RUN_INIT)
|
erl -pa ebin -mnesia dir $(MNESIA_DIR) $(RUN_INIT)
|
||||||
|
|
||||||
|
|
||||||
|
debug : DEBUG = +debug_info
|
||||||
|
debug : RUN_INIT = -s debugger start
|
||||||
|
debug : all
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
-module(ezic).
|
-module(ezic).
|
||||||
|
-export([load/1, time2time/3]).
|
||||||
-export([refresh_db/1]).
|
|
||||||
-export([time2time/3]).
|
|
||||||
|
|
||||||
|
|
||||||
refresh_db(_Folder) ->
|
load(Folder) ->
|
||||||
void.
|
ezic_loader:load(Folder).
|
||||||
|
|
||||||
|
|
||||||
time2time(_DateTime, _FromTimeZone, _ToTimeZone) ->
|
time2time(_DateTime, _FromTimeZone, _ToTimeZone) ->
|
||||||
void.
|
void.
|
||||||
|
|||||||
95
src/ezic_loader.erl
Normal file
95
src/ezic_loader.erl
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
-module(ezic_loader).
|
||||||
|
-include("include/ezic.hrl").
|
||||||
|
-export([load/1]).
|
||||||
|
|
||||||
|
|
||||||
|
load(File) ->
|
||||||
|
{ok, Records} =
|
||||||
|
case filelib:is_dir(File) of
|
||||||
|
true -> {ok, parse_dir(File)};
|
||||||
|
false -> case filelib:is_regular(File) of
|
||||||
|
true -> {ok, parse_file(File)};
|
||||||
|
false -> {error, {badFile, File}}
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
flatten(Records).
|
||||||
|
% @todo store in mnesia
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
% INTERNAL
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
% returns a list of tzdata records for all files in folder
|
||||||
|
% note: assumes every file in the folder is a tzdata file
|
||||||
|
% this method does not recurse.
|
||||||
|
parse_dir(Folder) ->
|
||||||
|
{ok, Files} = file:list_dir(Folder),
|
||||||
|
lists:flatten([ parse_file(filename:join(Folder,File)) || File <- Files ]).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
% returns a list of tzdata records from file
|
||||||
|
parse_file(File) ->
|
||||||
|
{ok, FD} = file:open(File, [read]),
|
||||||
|
parse_lines(file:read_line(FD), FD, []).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
parse_lines(eof, _, Records) ->
|
||||||
|
Records;
|
||||||
|
parse_lines({ok, Line}, File, Records) ->
|
||||||
|
StrLine= clean_line(Line),
|
||||||
|
case length(StrLine) > 0 of
|
||||||
|
false -> parse_lines(file:read_line(File), File, Records);
|
||||||
|
true -> parse_lines_2(StrLine, File, Records)
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
parse_lines_2(Line, File, Records) ->
|
||||||
|
[Type | Data] = string:tokens(Line, " \t"),
|
||||||
|
{ok, PrevType, PrevName} = prev_rec_type(Records),
|
||||||
|
{ok, Record} = build_record(Type, Data, {PrevType, PrevName}),
|
||||||
|
parse_lines(file:read_line(File), File, [Record|Records]).
|
||||||
|
|
||||||
|
|
||||||
|
prev_rec_type([]) ->
|
||||||
|
{ok, null, null};
|
||||||
|
prev_rec_type([#zone{name=Name}|_]) ->
|
||||||
|
{ok, "Zone", Name};
|
||||||
|
prev_rec_type(List) when is_list(List) ->
|
||||||
|
{ok, void, void}.
|
||||||
|
|
||||||
|
clean_line(Line) ->
|
||||||
|
Line1= string:strip(Line),
|
||||||
|
Line2= string:strip(Line1, both, $\n),
|
||||||
|
CPos= string:chr(Line2, $#),
|
||||||
|
case CPos of
|
||||||
|
0 -> Line2;
|
||||||
|
_ -> string:sub_string(Line2, 1, CPos-1)
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
build_record("Rule", Data,_) ->
|
||||||
|
ezic_record:rule(Data);
|
||||||
|
build_record("Zone", Data,_) ->
|
||||||
|
ezic_record:zone(Data);
|
||||||
|
build_record("Link", Data,_) ->
|
||||||
|
ezic_record:link(Data);
|
||||||
|
build_record(GmtOff, Data, {"Zone", PrevName}) ->
|
||||||
|
ezic_record:zone([PrevName,GmtOff|Data]);
|
||||||
|
|
||||||
|
build_record(Type, Data, PT) ->
|
||||||
|
{error, {badLine, Type, Data, PT}}.
|
||||||
|
|
||||||
|
|
||||||
|
% converts tzdata records to flattened records
|
||||||
|
% returns list of #flatzone{}
|
||||||
|
flatten(Records) when is_list(Records) ->
|
||||||
|
void.
|
||||||
82
src/ezic_record.erl
Normal file
82
src/ezic_record.erl
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
-module(ezic_record).
|
||||||
|
-include("include/ezic.hrl").
|
||||||
|
-export([rule/1,zone/1,link/1]).
|
||||||
|
|
||||||
|
|
||||||
|
rule([Name,From,To,Type,In,On,At,Save,Letters]) ->
|
||||||
|
{ok, #rule{
|
||||||
|
name=Name, from=From, to=To, type=Type,
|
||||||
|
in=In, on=On, at=At, save=Save, letters=Letters
|
||||||
|
}}.
|
||||||
|
|
||||||
|
zone([Name,GmtOff,Rules,Format | UntilTokens]) ->
|
||||||
|
Until = parse_until(UntilTokens),
|
||||||
|
{ok, #zone{
|
||||||
|
name=Name, gmtoff=GmtOff, rules=Rules,
|
||||||
|
format=Format, until=Until
|
||||||
|
}}.
|
||||||
|
|
||||||
|
link([From,To]) ->
|
||||||
|
{ok, #link{from=From, to=To}}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
% INTERNAL
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
|
parse_until([]) ->
|
||||||
|
current;
|
||||||
|
parse_until([YS]) ->
|
||||||
|
Y= list_to_integer(YS),
|
||||||
|
{Y,1,1};
|
||||||
|
parse_until([YS,MS]) ->
|
||||||
|
Y= list_to_integer(YS),
|
||||||
|
M=month_to_num(MS),
|
||||||
|
{Y,M,1};
|
||||||
|
parse_until([YS,MS,DS]) ->
|
||||||
|
Y= list_to_integer(YS),
|
||||||
|
M=month_to_num(MS),
|
||||||
|
D= list_to_integer(DS),
|
||||||
|
{Y,M,D};
|
||||||
|
% @todo broken: time flags must be accounted for
|
||||||
|
parse_until([YS,MS,DS,TS]) ->
|
||||||
|
Y= list_to_integer(YS),
|
||||||
|
M=month_to_num(MS),
|
||||||
|
D= list_to_integer(DS),
|
||||||
|
TimeTokens=string:tokens(TS, ":"),
|
||||||
|
{{Y,M,D},parse_time(TimeTokens)}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
parse_time("-") ->
|
||||||
|
{0,0,0};
|
||||||
|
parse_time([HS]) ->
|
||||||
|
H= list_to_integer(HS),
|
||||||
|
{H,0,0};
|
||||||
|
parse_time([HS,MS]) ->
|
||||||
|
H= list_to_integer(HS),
|
||||||
|
M= list_to_integer(MS),
|
||||||
|
{H,M,0};
|
||||||
|
parse_time([HS,MS,SS]) ->
|
||||||
|
H= list_to_integer(HS),
|
||||||
|
M= list_to_integer(MS),
|
||||||
|
S= list_to_integer(SS),
|
||||||
|
{H,M,S}.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
month_to_num("Jan") -> 1;
|
||||||
|
month_to_num("Feb") -> 2;
|
||||||
|
month_to_num("Mar") -> 3;
|
||||||
|
month_to_num("Apr") -> 4;
|
||||||
|
month_to_num("May") -> 5;
|
||||||
|
month_to_num("Jun") -> 6;
|
||||||
|
month_to_num("Jul") -> 7;
|
||||||
|
month_to_num("Aug") -> 8;
|
||||||
|
month_to_num("Sep") -> 9;
|
||||||
|
month_to_num("Oct") -> 10;
|
||||||
|
month_to_num("Nov") -> 11;
|
||||||
|
month_to_num("Dec") -> 12.
|
||||||
Reference in New Issue
Block a user