summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--socket.c2
-rw-r--r--stdlib/doc-syms.tl1
-rw-r--r--stdlib/socket.tl28
-rw-r--r--tests/014/str-addr.tl68
-rw-r--r--txr.142
5 files changed, 140 insertions, 1 deletions
diff --git a/socket.c b/socket.c
index f49c4005..dfa6cff0 100644
--- a/socket.c
+++ b/socket.c
@@ -1259,7 +1259,7 @@ static val sock_set_entries(val fun)
val name_noload[] = {
lit("family"), lit("addr"), lit("port"), lit("flow-info"),
lit("scope-id"), lit("prefix"), lit("path"), lit("flags"), lit("socktype"),
- lit("protocol"), lit("canonname"), nil
+ lit("protocol"), lit("canonname"), lit("str-addr"), nil
};
autoload_set(al_struct, sname, fun);
autoload_set(al_var, vname, fun);
diff --git a/stdlib/doc-syms.tl b/stdlib/doc-syms.tl
index 7d8c30b9..30c81243 100644
--- a/stdlib/doc-syms.tl
+++ b/stdlib/doc-syms.tl
@@ -1865,6 +1865,7 @@
("static-slot-set" "N-0017D1B5")
("stdlib" "N-008E4BC2")
("str" "D-005E")
+ ("str-addr" "N-02E1B78B")
("str-buf" "N-012BF6AD")
("str-d" "N-01736060")
("str-in6addr" "N-01FF658D")
diff --git a/stdlib/socket.tl b/stdlib/socket.tl
index 95a5650d..0e91eb17 100644
--- a/stdlib/socket.tl
+++ b/stdlib/socket.tl
@@ -290,3 +290,31 @@
((contains "." str) (inaddr-str str))
(t (or (ignerr (in6addr-str str))
(inaddr-str str)))))
+
+(defmeth sockaddr-in str-addr (me)
+ (let* ((pfx me.prefix)
+ (port me.port)
+ (addr me.addr)
+ (str (if (and pfx (< pfx 32))
+ (str-inaddr-net addr pfx)
+ (str-inaddr addr))))
+ (if (and port (plusp port))
+ `@str:@port`
+ str)))
+
+(defmeth sockaddr-in6 str-addr (me)
+ (let* ((pfx me.prefix)
+ (port me.port)
+ (addr me.addr)
+ (str (if (and pfx (< pfx 128))
+ (str-in6addr-net addr pfx)
+ (str-in6addr addr))))
+ (if (and port (plusp port))
+ `[@str]:@port`
+ str)))
+
+(defmeth sockaddr-un str-addr (me)
+ (let ((path me.path))
+ (if (stringp me.path)
+ path
+ (error "~s: slot path of ~s isn't a string" '(meth socakddr-un str-addr) me))))
diff --git a/tests/014/str-addr.tl b/tests/014/str-addr.tl
new file mode 100644
index 00000000..49bc844a
--- /dev/null
+++ b/tests/014/str-addr.tl
@@ -0,0 +1,68 @@
+(load "../common.tl")
+
+(mtest
+ #S(sockaddr-un path "/foo").(str-addr) "/foo"
+ #S(sockaddr-un path nil).(str-addr) :error)
+
+(mtest
+ #S(sockaddr-in addr 0).(str-addr) "0.0.0.0"
+ #S(sockaddr-in addr #x01020304).(str-addr) "1.2.3.4"
+ #S(sockaddr-in addr #x01020304 prefix 8).(str-addr) "1.2.3.4/8"
+ #S(sockaddr-in addr #x01020304 prefix 16).(str-addr) "1.2.3.4/16"
+ #S(sockaddr-in addr #x01020304 prefix 24).(str-addr) "1.2.3.4/24"
+ #S(sockaddr-in addr #x01020304 prefix 31).(str-addr) "1.2.3.4/31"
+ #S(sockaddr-in addr #x01020304 prefix 32).(str-addr) "1.2.3.4"
+ #S(sockaddr-in addr #x01000000 prefix 8).(str-addr) "1/8"
+ #S(sockaddr-in addr #x01000000 prefix 16).(str-addr) "1/16"
+ #S(sockaddr-in addr #x01020000 prefix 16).(str-addr) "1.2/16"
+ #S(sockaddr-in addr #x01000000 prefix 24).(str-addr) "1/24"
+ #S(sockaddr-in addr #x01020000 prefix 24).(str-addr) "1.2/24"
+ #S(sockaddr-in addr #x01020300 prefix 24).(str-addr) "1.2.3/24"
+ #S(sockaddr-in addr #x01000000 prefix 31).(str-addr) "1/31"
+ #S(sockaddr-in addr 0 port 123).(str-addr) "0.0.0.0:123"
+ #S(sockaddr-in addr #x01020304 port 123).(str-addr) "1.2.3.4:123"
+ #S(sockaddr-in addr #x01020304 port 123 prefix 8).(str-addr) "1.2.3.4/8:123"
+ #S(sockaddr-in addr #x01020304 port 123 prefix 16).(str-addr) "1.2.3.4/16:123"
+ #S(sockaddr-in addr #x01020304 port 123 prefix 24).(str-addr) "1.2.3.4/24:123"
+ #S(sockaddr-in addr #x01020304 port 123 prefix 24).(str-addr) "1.2.3.4/24:123"
+ #S(sockaddr-in addr #x01020304 port 123 prefix 31).(str-addr) "1.2.3.4/31:123"
+ #S(sockaddr-in addr #x01020304 port 123 prefix 32).(str-addr) "1.2.3.4:123"
+ #S(sockaddr-in addr #x01000000 port 123 prefix 8).(str-addr) "1/8:123"
+ #S(sockaddr-in addr #x01000000 port 123 prefix 16).(str-addr) "1/16:123"
+ #S(sockaddr-in addr #x01020000 port 123 prefix 16).(str-addr) "1.2/16:123"
+ #S(sockaddr-in addr #x01000000 port 123 prefix 24).(str-addr) "1/24:123"
+ #S(sockaddr-in addr #x01020000 port 123 prefix 24).(str-addr) "1.2/24:123"
+ #S(sockaddr-in addr #x01020300 port 123 prefix 24).(str-addr) "1.2.3/24:123"
+ #S(sockaddr-in addr #x01000000 port 123 prefix 31).(str-addr) "1/31:123")
+
+(mtest
+ #S(sockaddr-in6 addr 0).(str-addr) "::"
+ #S(sockaddr-in6 addr #x80000000000000000000000000000001).(str-addr) "8000::1"
+ #S(sockaddr-in6 addr #x00000000000000000000000000000001).(str-addr) "::1"
+ #S(sockaddr-in6 addr #x80000000000000000000000000000000).(str-addr) "8000::"
+ #S(sockaddr-in6 addr #x00008000000000000000000000000001).(str-addr) "0:8000::1"
+ #S(sockaddr-in6 addr #x00000000000000000000000000010000).(str-addr) "::1:0"
+ #S(sockaddr-in6 addr #x00008000000000000000000000010000).(str-addr) "0:8000::1:0"
+ #S(sockaddr-in6 addr #x000000000000abcd0000000000000000).(str-addr) "0:0:0:abcd::"
+ #S(sockaddr-in6 addr #x0000000000000000abcd000000000000).(str-addr) "::abcd:0:0:0"
+ #S(sockaddr-in6 addr #x11112222333344445555666677778888).(str-addr) "1111:2222:3333:4444:5555:6666:7777:8888"
+ #S(sockaddr-in6 addr #x01000200030004000500060007000800).(str-addr) "100:200:300:400:500:600:700:800"
+ #S(sockaddr-in6 addr #x00008000000000000000000000010000 port 0).(str-addr) "0:8000::1:0"
+ #S(sockaddr-in6 addr #x00008000000000000000000000010000 port 123).(str-addr) "[0:8000::1:0]:123"
+ #S(sockaddr-in6 addr #x00008000000000000000000000010000 prefix 128).(str-addr) "0:8000::1:0"
+ #S(sockaddr-in6 addr #x00008000000000000000000000010000 prefix 127).(str-addr) "0:8000::1:0/127"
+ #S(sockaddr-in6 addr #x00008000000000000000000000010000 port 123 prefix 127).(str-addr) "[0:8000::1:0/127]:123")
+
+(mtest
+ #S(sockaddr-in6 addr #xffff00000000).(str-addr) "::ffff:0.0.0.0"
+ #S(sockaddr-in6 addr #xffff00000000 prefix 24).(str-addr) "::ffff:0/24"
+ #S(sockaddr-in6 addr #xffff01000000 prefix 24).(str-addr) "::ffff:1/24"
+ #S(sockaddr-in6 addr #xffff01020000 prefix 24).(str-addr) "::ffff:1.2/24"
+ #S(sockaddr-in6 addr #xffff01020300 prefix 24).(str-addr) "::ffff:1.2.3/24"
+ #S(sockaddr-in6 addr #xffff01020304 prefix 24).(str-addr) "::ffff:1.2.3.4/24"
+ #S(sockaddr-in6 addr #xffff00000000 port 123 ).(str-addr) "[::ffff:0.0.0.0]:123"
+ #S(sockaddr-in6 addr #xffff00000000 port 123 prefix 24).(str-addr) "[::ffff:0/24]:123"
+ #S(sockaddr-in6 addr #xffff01000000 port 123 prefix 24).(str-addr) "[::ffff:1/24]:123"
+ #S(sockaddr-in6 addr #xffff01020000 port 123 prefix 24).(str-addr) "[::ffff:1.2/24]:123"
+ #S(sockaddr-in6 addr #xffff01020300 port 123 prefix 24).(str-addr) "[::ffff:1.2.3/24]:123"
+ #S(sockaddr-in6 addr #xffff01020304 port 123 prefix 24).(str-addr) "[::ffff:1.2.3.4/24]:123")
diff --git a/txr.1 b/txr.1
index 11ffebd6..4e5b8575 100644
--- a/txr.1
+++ b/txr.1
@@ -75495,6 +75495,48 @@ is passed to
.codn inaddr-str .
.RE
+.coNP Method @ str-addr
+.synb
+.mets << sockaddr .(str-addr)
+.syne
+.desc
+A method named
+.code str-addr
+is defined for the struct types
+.codn sockaddr-in ,
+.code sockaddr-in6
+and
+.codn sockaddr-un .
+It returns a text representation of the address as a string. If the
+.code port
+slot of
+.code sockaddr-in
+or
+.code sockaddr-in6
+is a nonzero integer, then it is incorporated into the text representation.
+Likewise if the
+.code prefix
+slot has a non-default value specifying fewer bits than the width of
+the address, the prefix notation is produced.
+
+The intent is that the representations produced are suitable as input
+to the
+.code sockaddr-str
+function which will reproducing an address object of the same type,
+featuring the same
+.codn addr ,
+.code port
+and
+.codn prefix .
+In the case of
+.codn sockaddr-un ,
+the
+.code sockaddr-str
+function will reproduce the same address only if the
+.code path
+slot is a string starting with
+.strn / .
+
.SS* Unix Terminal Control
\*(TX provides access to the terminal control "termios" interfaces defined by