PreviousUpNext

15.4.1490  src/lib/x-kit/xclient/pkg/wire/crack-xserver-address.pkg

## crack-xserver-address.pkg
#
# A little utility to analyse user-level
# X server specs, often from a DISPLAY
# unix environment string, something like:
#     ":0.0"
#     "foo.com:0.0"
#     "192.168.0.0:0.0"
#
# This is basically dedicated support for
#
#     src/lib/x-kit/xclient/pkg/wire/display.pkg

# Compiled by:
#     src/lib/x-kit/xclient/xclient-internals.sublib


stipulate
    package ss =  substring;                            # substring             is from   src/lib/std/substring.pkg
    package f  =  sfprintf;                             # sfprintf              is from   src/lib/src/sfprintf.pkg
herein


    package   crack_xserver_address
    : (weak)  Crack_Xserver_Address                     # Crack_Xserver_Address is from   src/lib/x-kit/xclient/pkg/wire/crack-xserver-address.api
    {

        Xserver_Address
          = UNIX  String                                #  ":display.screen" 
          | INET_HOSTNAME  (String, Int)                #  "hostname: display.screen" 
          | INET_ADDRESS   (String, Int)                #  "ddd.ddd.ddd.ddd: display.screen" 
          ;

        exception XSERVER_CONNECT_ERROR  String;

        x_tcpport  =  6000;
        x_unixpath =  "/tmp/.X11-unix/X";

        fun to_string  address
            =    
            case address
                #
                UNIX address'               =>  sprintf "UNIX '%s'" address';
                INET_HOSTNAME (string, int) =>  sprintf "INET_HOSTNAME ('%s',%d)" string int;
                INET_ADDRESS  (string, int) =>  sprintf "INET_ADDRESS  ('%s',%d)" string int;
            esac;

        fun find_char c (s, j)
            =
            find j
            where
                fun find i
                    =
                    if (string::get (s, i) == c)  i;
                    else                          find (i+1);
                    fi;
            end;


        fun make_unix_address (display_number, screen)
            =
            {   address                =>  UNIX (x_unixpath + (int::to_string display_number)),
                canonical_display_name =>  f::sprintf' "unix:%d.%d" [f::INT display_number, f::INT screen],
                screen
            };


        fun make_internet_address (host, display_number, screen)
            =
            if  (char::is_digit (string::get (host, 0)))
                #
                { address                =>  INET_ADDRESS (host, x_tcpport+display_number),
                  canonical_display_name =>  f::sprintf' "%s:%d.%d" [f::STRING host, f::INT display_number, f::INT screen],
                  screen
                };
            else
                { address                =>  INET_HOSTNAME (host, x_tcpport+display_number),
                  canonical_display_name =>  f::sprintf' "%s:%d.%d" [f::STRING host, f::INT display_number, f::INT screen],
                  screen
                };
            fi;


        fun crack_xserver_address  ""
                =>
                make_unix_address (0, 0);

            crack_xserver_address  string
                =>
                {
                    fun convert_int  substring
                        =
                        case (int::scan  number_string::DECIMAL  substring::getc  substring)
                            #                 
                            THE (n, _) =>  n;
                            NULL       =>  raise exception XSERVER_CONNECT_ERROR "expected integer";
                        esac;

                    # Split "127.0.0.1:0.0"  ->  ("127.0.0.1", "0.0")
                    #
                    my (hostname, rest)
                        =
                        ( ss::to_string  a,
                          ss::drop_first 1 b                    # The "drop_first" is to drop the leading ':' from ":0.0"
                        )
                        where                                   # split_off_prefix      def in    src/lib/core/init/substring.pkg
                            my (a, b)
                                =
                                ss::split_off_prefix

                                    .{ #c != ':'; }

                                    (ss::from_string string);

                        end;

                    # split "0.0" -> [ "0", "0" ]:
                    #
                    display_screen
                        =
                        ss::tokens
                            #
                            fn '.' =>  TRUE;
                                _  =>  FALSE;
                            end
                            #
                            rest;


                    my (display, screen)
                        =
                        case display_screen
                            #
                            [display]         =>  (convert_int display, 0);
                            [display, screen] =>  (convert_int display, convert_int screen);
                            #
                            []         =>  raise exception XSERVER_CONNECT_ERROR "missing display";
                            _          =>  raise exception XSERVER_CONNECT_ERROR "badly formed address";
                        esac;


                    case hostname
                        #                 
                        ""     =>  make_unix_address (display, screen);
                        "unix" =>  make_unix_address (display, screen);
                        name   =>  make_internet_address (name, display, screen);
                    esac;
                };
        end;

    };          # package crack_xserver_address
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext