Skip to content

Commit 742d967

Browse files
committed
Reuse parse code via macros
1 parent 385efe5 commit 742d967

1 file changed

Lines changed: 72 additions & 117 deletions

File tree

lib/kernel/src/inet_parse.erl

Lines changed: 72 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -577,83 +577,65 @@ ipv4strict_addr(Cs) ->
577577
%% Four functions, one per octet — no packed accumulator, no dot
578578
%% counter, no bit unpacking.
579579

580+
-define(is_octet_seq(__D1), (is_integer(__D1, $0, $9))).
581+
-define(is_octet_seq(__D1, __D2), (is_integer(__D1, $1, $9) andalso is_integer(__D2, $0, $9))).
582+
-define(is_octet_seq(__D1, __D2, __D3), (__D1 =:= $2 andalso __D2 =:= $5 andalso is_integer(__D3, $0, $5) orelse
583+
__D1 =:= $2 andalso is_integer(__D2, $0, $4) andalso is_integer(__D3, $0, $9) orelse
584+
__D1 =:= $1 andalso is_integer(__D2, $0, $9) andalso is_integer(__D3, $0, $9))).
585+
586+
-define(octet_seq_to_int(__D1), (__D1 - $0)).
587+
-define(octet_seq_to_int(__D1, __D2), (?octet_seq_to_int(__D1) * 10 + ?octet_seq_to_int(__D2))).
588+
-define(octet_seq_to_int(__D1, __D2, __D3), (?octet_seq_to_int(__D1) * 100 + ?octet_seq_to_int(__D2, __D3))).
589+
580590
%% --- Octet 1 (followed by dot) ---
581-
ipv4s_c1([D1, D2, D3, $. | R])
582-
when is_integer(D1, $1, $2),
583-
is_integer(D2, $0, $9),
584-
is_integer(D3, $0, $9) ->
585-
V = (D1 - $0) * 100 + (D2 - $0) * 10 + (D3 - $0),
586-
case V =< 255 of
587-
true -> ipv4s_c2(R, V);
588-
false -> erlang:error(badarg)
589-
end;
590-
ipv4s_c1([D1, D2, $. | R])
591-
when is_integer(D1, $1, $9),
592-
is_integer(D2, $0, $9) ->
593-
ipv4s_c2(R, (D1 - $0) * 10 + (D2 - $0));
594591
ipv4s_c1([D1, $. | R])
595-
when is_integer(D1, $0, $9) ->
596-
ipv4s_c2(R, D1 - $0);
592+
when ?is_octet_seq(D1) ->
593+
ipv4s_c2(R, ?octet_seq_to_int(D1));
594+
ipv4s_c1([D1, D2, $. | R])
595+
when ?is_octet_seq(D1, D2) ->
596+
ipv4s_c2(R, ?octet_seq_to_int(D1, D2));
597+
ipv4s_c1([D1, D2, D3, $. | R])
598+
when ?is_octet_seq(D1, D2, D3) ->
599+
ipv4s_c2(R, ?octet_seq_to_int(D1, D2, D3));
597600
ipv4s_c1(_) ->
598601
erlang:error(badarg).
599602

600603
%% --- Octet 2 (followed by dot) ---
601-
ipv4s_c2([D1, D2, D3, $. | R], A)
602-
when is_integer(D1, $1, $2),
603-
is_integer(D2, $0, $9),
604-
is_integer(D3, $0, $9) ->
605-
V = (D1 - $0) * 100 + (D2 - $0) * 10 + (D3 - $0),
606-
case V =< 255 of
607-
true -> ipv4s_c3(R, A, V);
608-
false -> erlang:error(badarg)
609-
end;
610-
ipv4s_c2([D1, D2, $. | R], A)
611-
when is_integer(D1, $1, $9),
612-
is_integer(D2, $0, $9) ->
613-
ipv4s_c3(R, A, (D1 - $0) * 10 + (D2 - $0));
614604
ipv4s_c2([D1, $. | R], A)
615-
when is_integer(D1, $0, $9) ->
616-
ipv4s_c3(R, A, D1 - $0);
605+
when ?is_octet_seq(D1) ->
606+
ipv4s_c3(R, A, ?octet_seq_to_int(D1));
607+
ipv4s_c2([D1, D2, $. | R], A)
608+
when ?is_octet_seq(D1, D2) ->
609+
ipv4s_c3(R, A, ?octet_seq_to_int(D1, D2));
610+
ipv4s_c2([D1, D2, D3, $. | R], A)
611+
when ?is_octet_seq(D1, D2, D3) ->
612+
ipv4s_c3(R, A, ?octet_seq_to_int(D1, D2, D3));
617613
ipv4s_c2(_, _) ->
618614
erlang:error(badarg).
619615

620616
%% --- Octet 3 (followed by dot) ---
621-
ipv4s_c3([D1, D2, D3, $. | R], A, B)
622-
when is_integer(D1, $1, $2),
623-
is_integer(D2, $0, $9),
624-
is_integer(D3, $0, $9) ->
625-
V = (D1 - $0) * 100 + (D2 - $0) * 10 + (D3 - $0),
626-
case V =< 255 of
627-
true -> ipv4s_c4(R, A, B, V);
628-
false -> erlang:error(badarg)
629-
end;
630-
ipv4s_c3([D1, D2, $. | R], A, B)
631-
when is_integer(D1, $1, $9),
632-
is_integer(D2, $0, $9) ->
633-
ipv4s_c4(R, A, B, (D1 - $0) * 10 + (D2 - $0));
634617
ipv4s_c3([D1, $. | R], A, B)
635-
when is_integer(D1, $0, $9) ->
636-
ipv4s_c4(R, A, B, D1 - $0);
618+
when ?is_octet_seq(D1) ->
619+
ipv4s_c4(R, A, B, ?octet_seq_to_int(D1));
620+
ipv4s_c3([D1, D2, $. | R], A, B)
621+
when ?is_octet_seq(D1, D2) ->
622+
ipv4s_c4(R, A, B, ?octet_seq_to_int(D1, D2));
623+
ipv4s_c3([D1, D2, D3, $. | R], A, B)
624+
when ?is_octet_seq(D1, D2, D3) ->
625+
ipv4s_c4(R, A, B, ?octet_seq_to_int(D1, D2, D3));
637626
ipv4s_c3(_, _, _) ->
638627
erlang:error(badarg).
639628

640629
%% --- Octet 4 (end of list) ---
641-
ipv4s_c4([D1, D2, D3], A, B, C)
642-
when is_integer(D1, $1, $2),
643-
is_integer(D2, $0, $9),
644-
is_integer(D3, $0, $9) ->
645-
V = (D1 - $0) * 100 + (D2 - $0) * 10 + (D3 - $0),
646-
case V =< 255 of
647-
true -> {A, B, C, V};
648-
false -> erlang:error(badarg)
649-
end;
650-
ipv4s_c4([D1, D2], A, B, C)
651-
when is_integer(D1, $1, $9),
652-
is_integer(D2, $0, $9) ->
653-
{A, B, C, (D1 - $0) * 10 + (D2 - $0)};
654630
ipv4s_c4([D1], A, B, C)
655-
when is_integer(D1, $0, $9) ->
656-
{A, B, C, D1 - $0};
631+
when ?is_octet_seq(D1) ->
632+
{A, B, C, ?octet_seq_to_int(D1)};
633+
ipv4s_c4([D1, D2], A, B, C)
634+
when ?is_octet_seq(D1, D2) ->
635+
{A, B, C, ?octet_seq_to_int(D1, D2)};
636+
ipv4s_c4([D1, D2, D3], A, B, C)
637+
when ?is_octet_seq(D1, D2, D3) ->
638+
{A, B, C, ?octet_seq_to_int(D1, D2, D3)};
657639
ipv4s_c4(_, _, _, _) ->
658640
erlang:error(badarg).
659641

@@ -687,81 +669,54 @@ ipv4strict_addr_bin(Bin) when is_binary(Bin) ->
687669
%% BEAM reuses the match context throughout.
688670

689671
%% --- Octet 1 (followed by dot) ---
690-
ipv4s_o1(<<D1, D2, D3, $., R/binary>>)
691-
when $1 =< D1, D1 =< $2,
692-
$0 =< D2, D2 =< $9,
693-
$0 =< D3, D3 =< $9 ->
694-
V = (D1 - $0) * 100 + (D2 - $0) * 10 + (D3 - $0),
695-
case V =< 255 of
696-
true -> ipv4s_o2(R, V);
697-
false -> error
698-
end;
699-
ipv4s_o1(<<D1, D2, $., R/binary>>)
700-
when $1 =< D1, D1 =< $9,
701-
$0 =< D2, D2 =< $9 ->
702-
ipv4s_o2(R, (D1 - $0) * 10 + (D2 - $0));
703672
ipv4s_o1(<<D1, $., R/binary>>)
704-
when $0 =< D1, D1 =< $9 ->
705-
ipv4s_o2(R, D1 - $0);
673+
when ?is_octet_seq(D1) ->
674+
ipv4s_o2(R, ?octet_seq_to_int(D1));
675+
ipv4s_o1(<<D1, D2, $., R/binary>>)
676+
when ?is_octet_seq(D1, D2) ->
677+
ipv4s_o2(R, ?octet_seq_to_int(D1, D2));
678+
ipv4s_o1(<<D1, D2, D3, $., R/binary>>)
679+
when ?is_octet_seq(D1, D2, D3) ->
680+
ipv4s_o2(R, ?octet_seq_to_int(D1, D2, D3));
706681
ipv4s_o1(_) ->
707682
error.
708683

709684
%% --- Octet 2 (followed by dot) ---
710-
ipv4s_o2(<<D1, D2, D3, $., R/binary>>, A)
711-
when $1 =< D1, D1 =< $2,
712-
$0 =< D2, D2 =< $9,
713-
$0 =< D3, D3 =< $9 ->
714-
V = (D1 - $0) * 100 + (D2 - $0) * 10 + (D3 - $0),
715-
case V =< 255 of
716-
true -> ipv4s_o3(R, A, V);
717-
false -> error
718-
end;
719-
ipv4s_o2(<<D1, D2, $., R/binary>>, A)
720-
when $1 =< D1, D1 =< $9,
721-
$0 =< D2, D2 =< $9 ->
722-
ipv4s_o3(R, A, (D1 - $0) * 10 + (D2 - $0));
723685
ipv4s_o2(<<D1, $., R/binary>>, A)
724-
when $0 =< D1, D1 =< $9 ->
725-
ipv4s_o3(R, A, D1 - $0);
686+
when ?is_octet_seq(D1) ->
687+
ipv4s_o3(R, A, ?octet_seq_to_int(D1));
688+
ipv4s_o2(<<D1, D2, $., R/binary>>, A)
689+
when ?is_octet_seq(D1, D2) ->
690+
ipv4s_o3(R, A, ?octet_seq_to_int(D1, D2));
691+
ipv4s_o2(<<D1, D2, D3, $., R/binary>>, A)
692+
when ?is_octet_seq(D1, D2, D3) ->
693+
ipv4s_o3(R, A, ?octet_seq_to_int(D1, D2, D3));
726694
ipv4s_o2(_, _) ->
727695
error.
728696

729697
%% --- Octet 3 (followed by dot) ---
730-
ipv4s_o3(<<D1, D2, D3, $., R/binary>>, A, B)
731-
when $1 =< D1, D1 =< $2,
732-
$0 =< D2, D2 =< $9,
733-
$0 =< D3, D3 =< $9 ->
734-
V = (D1 - $0) * 100 + (D2 - $0) * 10 + (D3 - $0),
735-
case V =< 255 of
736-
true -> ipv4s_o4(R, A, B, V);
737-
false -> error
738-
end;
739-
ipv4s_o3(<<D1, D2, $., R/binary>>, A, B)
740-
when $1 =< D1, D1 =< $9,
741-
$0 =< D2, D2 =< $9 ->
742-
ipv4s_o4(R, A, B, (D1 - $0) * 10 + (D2 - $0));
743698
ipv4s_o3(<<D1, $., R/binary>>, A, B)
744-
when $0 =< D1, D1 =< $9 ->
745-
ipv4s_o4(R, A, B, D1 - $0);
699+
when ?is_octet_seq(D1) ->
700+
ipv4s_o4(R, A, B, ?octet_seq_to_int(D1));
701+
ipv4s_o3(<<D1, D2, $., R/binary>>, A, B)
702+
when ?is_octet_seq(D1, D2) ->
703+
ipv4s_o4(R, A, B, ?octet_seq_to_int(D1, D2));
704+
ipv4s_o3(<<D1, D2, D3, $., R/binary>>, A, B)
705+
when ?is_octet_seq(D1, D2, D3) ->
706+
ipv4s_o4(R, A, B, ?octet_seq_to_int(D1, D2, D3));
746707
ipv4s_o3(_, _, _) ->
747708
error.
748709

749710
%% --- Octet 4 (end of binary) ---
750711
ipv4s_o4(<<D1, D2, D3>>, A, B, C)
751-
when $1 =< D1, D1 =< $2,
752-
$0 =< D2, D2 =< $9,
753-
$0 =< D3, D3 =< $9 ->
754-
V = (D1 - $0) * 100 + (D2 - $0) * 10 + (D3 - $0),
755-
case V =< 255 of
756-
true -> {A, B, C, V};
757-
false -> error
758-
end;
712+
when ?is_octet_seq(D1, D2, D3) ->
713+
{A, B, C, ?octet_seq_to_int(D1, D2, D3)};
759714
ipv4s_o4(<<D1, D2>>, A, B, C)
760-
when $1 =< D1, D1 =< $9, $0 =< D2, D2 =< $9 ->
761-
{A, B, C, (D1 - $0) * 10 + (D2 - $0)};
715+
when ?is_octet_seq(D1, D2) ->
716+
{A, B, C, ?octet_seq_to_int(D1, D2)};
762717
ipv4s_o4(<<D1>>, A, B, C)
763-
when $0 =< D1, D1 =< $9 ->
764-
{A, B, C, D1 - $0};
718+
when ?is_octet_seq(D1) ->
719+
{A, B, C, ?octet_seq_to_int(D1)};
765720
ipv4s_o4(_, _, _, _) ->
766721
error.
767722

0 commit comments

Comments
 (0)