getaddrinfo already returns the shortest textual form, so if you have the longer form you can canonicalize by running through getaddrinfo again. Example Python,
import sys, socket;
result = socket.getaddrinfo('0:0::0:1', None);
print "family:%i socktype:%i proto:%i canonname:%s sockaddr:%s"%result[0];
Outputs the following,
family:10 socktype:1 proto:6 canonname: sockaddr:('::1', 0, 0, 0)
IPv6 CIDR blocks don't appear to be well documented or defined so I wrote my own inet6_network implementation to handle that (C99).