var gtk2 = require('Gtk2') -> init;

var gui = %s'Gtk2::Builder'.new;
gui.add_from_string(DATA.slurp);

func clicked_ok(*_) {
    var entry = gui.get_object('entry1');
    var text = entry.get_text;

    var spinner = gui.get_object('spinbutton1');
    var number = spinner.get_text;

    say "string: #{text}";
    say "number: #{number}";

    number == 75000 ? gtk2.main_quit : warn "Invalid number!";
}

func clicked_cancel(*_) {
    gtk2.main_quit;
}

gui.get_object('button1').signal_connect('clicked', clicked_ok);
gui.get_object('button2').signal_connect('clicked', clicked_cancel);

gtk2.main;

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <requires lib="gtk+" version="2.24"/>
  <!-- interface-naming-policy project-wide -->
  <object class="GtkAdjustment" id="adjustment1">
    <property name="upper">100000</property>
    <property name="value">75000</property>
    <property name="step_increment">1</property>
    <property name="page_increment">10</property>
  </object>
  <object class="GtkWindow" id="window1">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <child>
      <object class="GtkVBox" id="vbox1">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkLabel" id="label1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">Please insert a string and a number:</property>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkHBox" id="hbox1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkLabel" id="label2">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">string:</property>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="padding">55</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkEntry" id="entry1">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="invisible_char">•</property>
                <property name="primary_icon_activatable">False</property>
                <property name="secondary_icon_activatable">False</property>
                <property name="primary_icon_sensitive">True</property>
                <property name="secondary_icon_sensitive">True</property>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkHBox" id="hbox2">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkLabel" id="label3">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">number:</property>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkSpinButton" id="spinbutton1">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="invisible_char">•</property>
                <property name="primary_icon_activatable">False</property>
                <property name="secondary_icon_activatable">False</property>
                <property name="primary_icon_sensitive">True</property>
                <property name="secondary_icon_sensitive">True</property>
                <property name="adjustment">adjustment1</property>
                <property name="numeric">True</property>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkHButtonBox" id="hbuttonbox1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="layout_style">spread</property>
            <child>
              <object class="GtkButton" id="button1">
                <property name="label">gtk-ok</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="use_stock">True</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">False</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="button2">
                <property name="label">gtk-cancel</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="use_stock">True</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">False</property>
                <property name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">True</property>
            <property name="fill">True</property>
            <property name="position">3</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>


open XWindows ;
open Motif ;

val store : string list ref = ref [] ;

val inputWindow = fn () =>
let
  val shell  =  XtAppInitialise      ""    "demo" "top" [] [ XmNwidth 320, XmNheight 100 ] ;
  val main   =  XmCreateMainWindow   shell    "main"       [ XmNmappedWhenManaged true   ] ;
  val enter  =  XmCreateText         main   "inputarea"    [ XmNeditMode XmSINGLE_LINE_EDIT,
                                                             XmNscrollHorizontal false   ] ;
  val getinp =  fn (w,s,t) => ( store := XmTextGetString enter :: !store   ; t )
in

  (
   XtSetCallbacks   enter [ (XmNactivateCallback , getinp) ] XmNarmCallback ;
   XtManageChild    enter ;
   XtManageChild    main  ;
   XtRealizeWidget  shell
  )

end ;

inputWindow () ;


# create entry widget:
pack [entry .e1]

# read its content:
set input [.e get]


Prgm
  Dialog
    Title "Rosetta Code"
    Request "A string", s
    DropDown "An integer", {"75000"}, n
  EndDlog
  74999 + n → n
EndPrgm


strUserIn = InputBox("Enter Data")
Wscript.Echo strUserIn


Dialog_Input_1(1, "`User Input example`,
                   `??Enter a string `,
                   `??Enter a number `")


import "graphics" for Canvas, Color
import "input" for Keyboard, Clipboard
import "dome" for Window, Process

var X = 10
var Y = 28

class Main {
    construct new() {}

    init() {
        _text = ""
        _enterNum = false
        Keyboard.handleText = true
        Keyboard.textRegion(X, Y, 8, 8)
    }

    update() {
        var change = false
        if (Keyboard.text.count > 0) {
            _text = _text + Keyboard.text
            change = true
        }

        // enable backspace key to delete last character entered
        if (Keyboard["backspace"].justPressed && _text.count > 0) {
            var codePoints = _text.codePoints
            codePoints = codePoints.take(codePoints.count - 1)
            _text = ""
            for (point in codePoints) {
                _text = _text + String.fromCodePoint(point)
            }
            change = true
        }

        // enable return key to terminate input
        if (Keyboard["return"].justPressed) {
            System.print("'%(_text)' was entered.")
            if (!_enterNum) {
                _text = ""
                _enterNum = true
                change = true
            } else if (_text == "75000") {
                Process.exit()
            } else {
                _text = ""
                change = true
            }
        }

        if (change) {
            Keyboard.textRegion(X.min(_text.count * 8), Y, 8, 8)
        }
    }

    draw(dt) {
        Canvas.cls()
        Canvas.rect(X, Y, 8, 8, Color.red)
        if (!_enterNum) {
            Canvas.print("Enter Text and press return:", 10, 10, Color.white)
        } else {
            Canvas.print("Enter 75000 and press return:", 10, 10, Color.white)
        }
        Canvas.print(_text, 10, 20, Color.white)
    }
}

var Game = Main.new()


F url_encode(s)
   V r = ‘’
   V buf = ‘’

   F flush_buf() // this function is needed because strings in 11l are UTF-16 encoded
      I @buf != ‘’
         V bytes = @buf.encode(‘utf-8’)
         L(b) bytes
            @r ‘’= ‘%’hex(b).zfill(2)
         @buf = ‘’

   L(c) s
      I c C (‘0’..‘9’, ‘a’..‘z’, ‘A’..‘Z’, ‘_’, ‘.’, ‘-’, ‘~’)
         flush_buf()
         r ‘’= c
      E
         buf ‘’= c

   flush_buf()
   R r

print(url_encode(‘http://foo bar/’))
print(url_encode(‘https://ru.wikipedia.org/wiki/Транспайлер’))


BYTE FUNC MustEncode(CHAR c CHAR ARRAY ex)
  BYTE i

  IF c>='a AND c<='z OR c>='A AND c<='Z OR c>='0 AND c<='9 THEN
    RETURN (0)
  FI
  IF ex(0)>0 THEN
    FOR i=1 TO ex(0)
    DO
      IF ex(i)=c THEN
        RETURN (0)
      FI
    OD
  FI
RETURN (1)

PROC Append(CHAR ARRAY s CHAR c)
  s(0)==+1
  s(s(0))=c
RETURN

PROC Encode(CHAR ARRAY in,out,ex BYTE spaceToPlus)
  CHAR ARRAY hex=['0 '1 '2 '3 '4 '5 '6 '7 '8 '9 'A 'B 'C 'D 'E 'F]
  BYTE i
  CHAR c

  out(0)=0
  FOR i=1 TO in(0)
  DO
    c=in(i)
    IF spaceToPlus=1 AND c=32 THEN
      Append(out,'+)
    ELSEIF MustEncode(c,ex) THEN
      Append(out,'%)
      Append(out,hex(c RSH 4))
      Append(out,hex(c&$0F))
    ELSE
      Append(out,c)
    FI
  OD
RETURN

PROC EncodeRaw(CHAR ARRAY in,out)
  Encode(in,out,"",0)
RETURN

PROC EncodeRFC3986(CHAR ARRAY in,out)
  Encode(in,out,"-._~",0)
RETURN

PROC EncodeHTML5(CHAR ARRAY in,out)
  Encode(in,out,"-._*",1)
RETURN

PROC PrintInv(CHAR ARRAY a)
  BYTE i

  IF a(0)>0 THEN
    FOR i=1 TO a(0)
    DO
      Put(a(i)%$80)
    OD
  FI
RETURN

PROC Test(CHAR ARRAY in)
  CHAR ARRAY out(256)

  PrintInv("input   ")
  PrintF(" %S%E",in)

  EncodeRaw(in,out)
  PrintInv("encoded ")
  PrintF(" %S%E",out)

  EncodeRFC3986(in,out)
  PrintInv("RFC 3986")
  PrintF(" %S%E",out)

  EncodeHTML5(in,out)
  PrintInv("HTML 5  ")
  PrintF(" %S%E%E",out)
RETURN

PROC Main()
  Test("http://foo bar/")
  Test("http://www.rosettacode.org/wiki/URL_encoding")
  Test("http://foo bar/*_-.html")
RETURN


with AWS.URL;
with Ada.Text_IO; use Ada.Text_IO;
procedure Encode is
   Normal : constant String := "http://foo bar/";
begin
   Put_Line (AWS.URL.Encode (Normal));
end Encode;


BEGIN
    # encodes the specified url - 0-9, A-Z and a-z are unchanged,            #
    # everything else is converted to %xx where xx are hex-digits            #
    PROC encode url = ( STRING url )STRING:
         IF url = "" THEN "" # empty string                                  #
         ELSE
            # non-empty string                                               #
            # ensure result will be big enough for a string of all encodable #
            # characters                                                     #
            STRING hex digits = "0123456789ABCDEF";
            [ 1 : ( ( UPB url - LWB url ) + 1 ) * 3 ]CHAR result;
            INT r pos := 0;
            FOR u pos FROM LWB url TO UPB url DO
                CHAR c = url[ u pos ];
                IF ( c >= "0" AND c <= "9" )
                OR ( c >= "A" AND c <= "Z" )
                OR ( c >= "a" AND c <= "z" )
                THEN
                    # no need to encode this character                       #
                    result[ r pos +:= 1 ] := c
                ELSE
                    # must encode                                            #
                    INT c code = ABS c;
                    result[ r pos +:= 1 ] := "%";
                    result[ r pos +:= 1 ] := hex digits[ ( c code OVER 16 ) + 1 ];
                    result[ r pos +:= 1 ] := hex digits[ ( c code  MOD 16 ) + 1 ]
                FI
            OD;
            result[ 1 : r pos ]
         FI; # encode url #
    # task test case                                                         #
    print( ( encode url( "http://foo bar/" ), newline ) )
END


encoded: encode.url.slashes "http://foo bar/"
print encoded


MsgBox, % UriEncode("http://foo bar/")

; Modified from http://goo.gl/0a0iJq
UriEncode(Uri)
{
	VarSetCapacity(Var, StrPut(Uri, "UTF-8"), 0)
	StrPut(Uri, &Var, "UTF-8")
	f := A_FormatInteger
	SetFormat, IntegerFast, H
	While Code := NumGet(Var, A_Index - 1, "UChar")
		If (Code >= 0x30 && Code <= 0x39 ; 0-9
			|| Code >= 0x41 && Code <= 0x5A ; A-Z
			|| Code >= 0x61 && Code <= 0x7A) ; a-z
			Res .= Chr(Code)
		Else
			Res .= "%" . SubStr(Code + 0x100, -1)
	SetFormat, IntegerFast, %f%
	Return, Res
}


BEGIN {
	for (i = 0; i <= 255; i++)
		ord[sprintf("%c", i)] = i
}

# Encode string with application/x-www-form-urlencoded escapes.
function escape(str,    c, len, res) {
	len = length(str)
	res = ""
	for (i = 1; i <= len; i++) {
		c = substr(str, i, 1);
		if (c ~ /[0-9A-Za-z]/)
		#if (c ~ /[-._*0-9A-Za-z]/)
			res = res c
		#else if (c == " ")
		#	res = res "+"
		else
			res = res "%" sprintf("%02X", ord[c])
	}
	return res
}

# Escape every line of input.
{ print escape($0) }


      PRINT FNurlencode("http://foo bar/")
      END

      DEF FNurlencode(url$)
      LOCAL c%, i%
      WHILE i% < LEN(url$)
        i% += 1
        c% = ASCMID$(url$, i%)
        IF c%<&30 OR c%>&7A OR c%>&39 AND c%<&41 OR c%>&5A AND c%<&61 THEN
          url$ = LEFT$(url$,i%-1) + "%" + RIGHT$("0"+STR$~c%,2) + MID$(url$,i%+1)
        ENDIF
      ENDWHILE
      = url$


(     ( encode
      =   encoded exceptions octet string
        .     !arg:(?exceptions.?string)
            & :?encoded
            & @( !string
               :   ?
                   ( %@?octet ?
                   &     !encoded
                         (   !octet
                           : ( ~<0:~>9
                             | ~<A:~>Z
                             | ~<a:~>z
                             )
                         |   @(!exceptions:? !octet ?)
                           & !octet
                         | "%" d2x$(asc$!octet)
                         )
                     : ?encoded
                   & ~
                   )
               )
          | str$!encoded
      )
    & out$"without exceptions:
"
    & out$(encode$(."http://foo bar/"))
    & out$(encode$(."mailto:Ivan"))
    & out$(encode$(."Aim <[email protected]>"))
    & out$(encode$(."mailto:Irma"))
    & out$(encode$(."User <[email protected]>"))
    & out$(encode$(."http://foo.bar.com/~user-name/_subdir/*~.html"))
    & out$"
with RFC 3986 rules:
"
    & out$(encode$("-._~"."http://foo bar/"))
    & out$(encode$("-._~"."mailto:Ivan"))
    & out$(encode$("-._~"."Aim <[email protected]>"))
    & out$(encode$("-._~"."mailto:Irma"))
    & out$(encode$("-._~"."User <[email protected]>"))
    & out$(encode$("-._~"."http://foo.bar.com/~user-name/_subdir/*~.html"))
);


#include <stdio.h>
#include <ctype.h>

char rfc3986[256] = {0};
char html5[256] = {0};

/* caller responsible for memory */
void encode(const char *s, char *enc, char *tb)
{
	for (; *s; s++) {
		if (tb[*s]) sprintf(enc, "%c", tb[*s]);
		else        sprintf(enc, "%%%02X", *s);
		while (*++enc);
	}
}

int main()
{
	const char url[] = "http://foo bar/";
	char enc[(strlen(url) * 3) + 1];

	int i;
	for (i = 0; i < 256; i++) {
		rfc3986[i] = isalnum(i)||i == '~'||i == '-'||i == '.'||i == '_'
			? i : 0;
		html5[i] = isalnum(i)||i == '*'||i == '-'||i == '.'||i == '_'
			? i : (i == ' ') ? '+' : 0;
	}

	encode(url, enc, rfc3986);
	puts(enc);

	return 0;
}


using System;

namespace URLEncode
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.WriteLine(Encode("http://foo bar/"));
        }

        private static string Encode(string uri)
        {
            return Uri.EscapeDataString(uri);
        }
    }
}


#include <QByteArray>
#include <iostream>

int main( ) {
   QByteArray text ( "http://foo bar/" ) ;
   QByteArray encoded( text.toPercentEncoding( ) ) ;
   std::cout << encoded.data( ) << '\n' ;
   return 0 ;
}


(import 'java.net.URLEncoder)
(URLEncoder/encode "http://foo bar/" "UTF-8")


(defun needs-encoding-p (char)
  (not (digit-char-p char 36)))

(defun encode-char (char)
  (format nil "%~2,'0X" (char-code char)))

(defun url-encode (url)
  (apply #'concatenate 'string
         (map 'list (lambda (char)
                      (if (needs-encoding-p char)
                          (encode-char char)
                          (string char)))
              url)))

(url-encode "http://foo bar/")


require "uri"

puts URI.encode("http://foo bar/")
puts URI.encode("http://foo bar/", space_to_plus: true)
puts URI.encode_www_form("http://foo bar/")
puts URI.encode_www_form("http://foo bar/", space_to_plus: false)


import std.stdio, std.uri;

void main() {
    writeln(encodeComponent("http://foo bar/"));
}


iex(1)> URI.encode("http://foo bar/", &URI.char_unreserved?/1)
"http%3A%2F%2Ffoo%20bar%2F"


1> http_uri:encode("http://foo bar/").
"http%3A%2F%2Ffoo%20bar%2F"


open System

[<EntryPoint>]
let main args =
    printfn "%s" (Uri.EscapeDataString(args.[0]))
    0


USING: combinators.short-circuit unicode urls.encoding.private ;

: my-url-encode ( str -- encoded )
    [ { [ alpha? ] [ "-._~" member? ] } 1|| ] (url-encode) ;

"http://foo bar/" my-url-encode print


function urlEncode(data: string): AnsiString;
var
  ch: AnsiChar;
begin
  Result := '';
  for ch in data do begin
    if ((Ord(ch) < 65) or (Ord(ch) > 90)) and ((Ord(ch) < 97) or (Ord(ch) > 122)) then begin
      Result := Result + '%' + IntToHex(Ord(ch), 2);
    end else
      Result := Result + ch;
  end;
end;


Dim Shared As String lookUp(256)
For cadena As Integer = 0 To 256
    lookUp(cadena) = "%" + Hex(cadena)
Next cadena

Function string2url(cadena As String) As String
    Dim As String cadTemp, cadDevu
    For j As Integer = 1 To Len(cadena)
        cadTemp = Mid(cadena, j, 1)
        If Instr( "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", cadTemp) Then
            cadDevu &= cadTemp
        Else
            cadDevu &= lookUp(Asc(cadTemp))
        End If
    Next j
    Return cadDevu
End Function

Dim As String URL = "http://foo bar/"

Print "Supplied URL '"; URL; "'"
Print "URL encoding '"; string2url(URL); "'"
Sleep


package main

import (
    "fmt"
    "net/url"
)

func main() {
    fmt.Println(url.QueryEscape("http://foo bar/"))
}


def normal = "http://foo bar/"
def encoded = URLEncoder.encode(normal, "utf-8")
println encoded


import qualified Data.Char as Char
import Text.Printf

encode :: Char -> String
encode c
  | c == ' ' = "+"
  | Char.isAlphaNum c || c `elem` "-._~" = [c]
  | otherwise = printf "%%%02X" c

urlEncode :: String -> String
urlEncode = concatMap encode

main :: IO ()
main = putStrLn $ urlEncode "http://foo bar/"


link hexcvt

procedure main()
write("text    = ",image(u := "http://foo bar/"))
write("encoded = ",image(ue := encodeURL(u)))
end

procedure encodeURL(s)           #: encode data for inclusion in a URL/URI
static en
initial {                           # build lookup table for everything
   en := table()
   every en[c := !string(~(&digits++&letters))] := "%"||hexstring(ord(c),2)
   every /en[c := !string(&cset)] := c
   }

every (c := "") ||:= en[!s]         # re-encode everything
return c
end


require'strings convert'
urlencode=: rplc&((#~2|_1 47 57 64 90 96 122 [email protected]#)a.;"_1'%',.hfd i.#a.)


import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

public class Main
{
    public static void main(String[] args) throws UnsupportedEncodingException
    {
        String normal = "http://foo bar/";
        String encoded = URLEncoder.encode(normal, "utf-8");
        System.out.println(encoded);
    }
}


var normal = 'http://foo/bar/';
var encoded = encodeURIComponent(normal);


//version 1.0.1
import HTTP.URIs: escapeuri

dcd = "http://foo bar/"
enc = escapeuri(dcd)

println(dcd, " => ", enc)


// version 1.1.2

import java.net.URLEncoder

fun main(args: Array<String>) {
    val url = "http://foo bar/"
    println(URLEncoder.encode(url, "utf-8")) // note: encodes space to + not %20
}


url_encode()
{
        printf "%(url)q\n" "$*"
}

url_encode "http://foo bar/"
url_encode "https://ru.wikipedia.org/wiki/Транспайлер"
url_encode "google.com/search?q=`Abdu'l-Bahá"


val .urlEncode = f(.s) replace(
    .s, re/[^A-Za-z0-9]/,
    f(.s2) for .b in s2b(.s2) { _for ~= $"%\.b:X02;" },
)

val .original = "https://some website.com/"

writeln .original
writeln .urlEncode(.original)


    dim lookUp$( 256)

    for i =0 to 256
        lookUp$( i) ="%" +dechex$( i)
    next i

    string$ ="http://foo bar/"

    print "Supplied string '"; string$; "'"
    print "As URL          '"; url$( string$); "'"

    end

function url$( i$)
    for j =1 to len( i$)
        c$ =mid$( i$, j, 1)
        if instr( "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", c$) then
            url$ =url$ +c$
        else
            url$ =url$ +lookUp$( asc( c$))
        end if
    next j
end function


put urlencode("http://foo bar/")
-- "http%3a%2f%2ffoo+bar%2f"


urlEncode("http://foo bar/")
-- http%3A%2F%2Ffoo+bar%2F


function encodeChar(chr)
	return string.format("%%%X",string.byte(chr))
end

function encodeString(str)
	local output, t = string.gsub(str,"[^%w]",encodeChar)
	return output
end

-- will print "http%3A%2F%2Ffoo%20bar%2F"
print(encodeString("http://foo bar/"))


Module Checkit {
            Function decodeUrl$(a$) {
                  DIM a$()
                  a$()=Piece$(a$, "%")
                  if len(a$())=1 then =str$(a$):exit
                  k=each(a$(),2)
                  acc$=str$(a$(0))
                  While k {
                  acc$+=str$(Chr$(Eval("0x"+left$(a$(k^),2)))+Mid$(a$(k^),3))
                  }
                  =string$(acc$ as utf8dec)
            }
            Group Parse$ {
                 all$, c=1
                 tc$=""
                 Enum UrlType {None=0, RFC3986, HTML5}
                 variation
                 TypeData=("","-._~","-._*")
                 Function Next {
                            .tc$<=mid$(.all$,.c,1)
                             .c++
                             =.tc$<>""
                  }
                  Value {
                        =.tc$
                  }
                  Function DecodeOne$ {
                        if .tc$="" then exit
                        if .tc$ ~"[A-Za-z0-9]" then =.tc$ : exit
                        If .tc$=" " Then =if$(.variation=.HTML5->"+","%20") :exit
                        if instr(.TypeData#val$(.variation),.tc$)>0 then =.tc$ :exit
                        ="%"+hex$(asc(.tc$), 1)
                  }
                  Function Decode$ {
                        acc$=""
                        .c<=1
                        While .Next()  {
                               acc$+=.DecodeOne$()
                        }
                        =acc$
                  }
                  Set () {
                        \\ using optional argument
                        var=.None
                        Read a$, ? var
                        a$=chr$(string$(a$ as utf8enc))
                        .variation<=var
                        .all$<=a$
                        .c<=1
                  }
            }
            \\ MAIN
            Parse$()="http://foo bar/"
            Print Quote$(Parse.Decode$())
            Parse.variation=Parse.HTML5
            Print Quote$(Parse.Decode$())
            Parse.variation=Parse.RFC3986
            Print Quote$(Parse.Decode$())
            Parse$(Parse.RFC3986) ={mailto:"Irma User" <[email protected]>}
            Print Quote$(Parse.Decode$())
            Parse$(Parse.RFC3986) ={http://foo.bar.com/~user-name/_subdir/*~.html}
            m=each(Parse.UrlType)
            while m {
                 Parse.variation=eval(m)
                 Print Quote$(Parse.Decode$())
                 Print decodeUrl$(Parse.Decode$())
            }
}
CheckIt


URLEncoding[url_] :=
 StringReplace[url,
  x : Except[
     Join[CharacterRange["0", "9"], CharacterRange["a", "z"],
      CharacterRange["A", "Z"]]] :>
   StringJoin[("%" ~~ #) & /@
     IntegerString[ToCharacterCode[x, "UTF8"], 16]]]


function u = urlencoding(s)
	u = '';
	for k = 1:length(s),
		if isalnum(s(k))
			u(end+1) = s(k);
		else
			u=[u,'%',dec2hex(s(k)+0)];
		end;
	end
end


/* NetRexx */
options replace format comments java crossref symbols nobinary

/* -------------------------------------------------------------------------- */
  testcase()
  say
  say 'RFC3986'
  testcase('RFC3986')
  say
  say 'HTML5'
  testcase('HTML5')
  say
  return

/* -------------------------------------------------------------------------- */
method encode(url, varn) public static

  variation = varn.upper
  opts = ''
  opts['RFC3986'] = '-._~'
  opts['HTML5']   = '-._*'

  rp = ''
  loop while url.length > 0
    parse url tc +1 url
    select
      when tc.datatype('A') then do
        rp = rp || tc
        end
      when tc == ' ' then do
        if variation = 'HTML5' then
          rp = rp || '+'
        else
          rp = rp || '%' || tc.c2x
        end
      otherwise do
        if opts[variation].pos(tc) > 0 then do
          rp = rp || tc
          end
        else do
          rp = rp || '%' || tc.c2x
          end
        end
      end
    end

  return rp

/* -------------------------------------------------------------------------- */
method testcase(variation = '') public static

  url = [ -
      'http://foo bar/' -
    , 'mailto:"Ivan Aim" <[email protected]>' -
    , 'mailto:"Irma User" <[email protected]>' -
    , 'http://foo.bar.com/~user-name/_subdir/*~.html' -
    ]

  loop i_ = 0 to url.length - 1
    say url[i_]
    say encode(url[i_], variation)
    end i_

  return


;; simple encoder
;; (source http://www.newlisp.org/index.cgi?page=Code_Snippets)
(define (url-encode str)
  (replace {([^a-zA-Z0-9])} str (format "%%%2X" (char $1)) 0))

(url-encode "http://foo bar/")


import cgi

echo encodeUrl("http://foo/bar/")


MODULE URLEncoding;
IMPORT
  Out := NPCT:Console,
  ADT:StringBuffer,
  URI := URI:String;
VAR
  encodedUrl: StringBuffer.StringBuffer;
BEGIN
  encodedUrl := NEW(StringBuffer.StringBuffer,512);
  URI.AppendEscaped("http://foo bar/","",encodedUrl);
  Out.String(encodedUrl.ToString());Out.Ln
END URLEncoding.


use FastCgi;

bundle Default {
  class UrlEncode {
    function : Main(args : String[]) ~ Nil {
      url := "http://foo bar/";
      UrlUtility->Encode(url)->PrintLine();
    }
  }
}


NSString *normal = @"http://foo bar/";
NSString *encoded = [normal stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", encoded);


$ ocaml
# #use "topfind";;
# #require "netstring";;

# Netencoding.Url.encode "http://foo bar/" ;;
- : string = "http%3A%2F%2Ffoo+bar%2F"


sub urlencode {
    my $s = shift;
    $s =~ s/([^-A-Za-z0-9_.!~*'() ])/sprintf("%%%02X", ord($1))/eg;
    $s =~ tr/ /+/;
    return $s;
}

print urlencode('http://foo bar/')."\n";


F url_decode(s)
   V r = ‘’
   V i = 0
   L i < s.len
      I s[i] == ‘%’
         [Byte] b
         L i < s.len & s[i] == ‘%’
            i++
            b.append(Int(s[i.+2], radix' 16))
            i += 2
         r ‘’= b.decode(‘utf-8’)
      E
         r ‘’= s[i]
         i++
   R r

print(url_decode(‘http%3A%2F%2Ffoo%20bar%2F’))
print(url_decode(‘https://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B0%D0%BD%D1%81%D0%BF%D0%B0%D0%B9%D0%BB%D0%B5%D1%80’))


--
-- demo\rosetta\encode_url.exw
-- ===========================
--
with javascript_semantics
function nib(integer b)
    return b+iff(b<=9?'0':'A'-10)
end function

function encode_url(string s, string exclusions="", integer spaceplus=0)
string res = ""
    for i=1 to length(s) do
        integer ch = s[i]
        if ch=' ' and spaceplus then
            ch = '+'
        elsif not find(ch,exclusions)
          and (ch<'0'
           or (ch>'9' and ch<'A')
           or (ch>'Z' and ch<'a')
           or  ch>'z') then
            res &= '%'
            res &= nib(floor(ch/#10))
            ch = nib(and_bits(ch,#0F))
        end if
        res &= ch
    end for
    return res
end function

printf(1,"%s\n",{encode_url("http://foo bar/")})
{} = wait_key()


<?php
$s = 'http://foo/bar/';
$s = rawurlencode($s);
?>


REPORT Z_DECODE_URL.

DATA: lv_encoded_url TYPE string VALUE 'http%3A%2F%2Ffoo%20bar%2F',
      lv_decoded_url TYPE string.

CALL METHOD CL_HTTP_UTILITY=>UNESCAPE_URL
  EXPORTING
    ESCAPED   = lv_encoded_url
  RECEIVING
    UNESCAPED = lv_decoded_url.

WRITE: 'Encoded URL: ', lv_encoded_url, /, 'Decoded URL: ', lv_decoded_url.


PROC Append(CHAR ARRAY s CHAR c)
  s(0)==+1
  s(s(0))=c
RETURN

CHAR FUNC GetCharFromHex(CHAR c1,c2)
  CHAR ARRAY hex=['0 '1 '2 '3 '4 '5 '6 '7 '8 '9 'A 'B 'C 'D 'E 'F]
  BYTE i,res

  res=0
  FOR i=0 TO 15
  DO
    IF c1=hex(i) THEN res==+i LSH 4 FI
    IF c2=hex(i) THEN res==+i FI
  OD
RETURN (res)

PROC Decode(CHAR ARRAY in,out)
  BYTE i
  CHAR c

  out(0)=0
  i=1
  WHILE i<=in(0)
  DO
    c=in(i)
    i==+1
    IF c='+ THEN
      Append(out,' )
    ELSEIF c='% THEN
      c=GetCharFromHex(in(i),in(i+1))
      i==+2
      Append(out,c)
    ELSE
      Append(out,c)
    FI
  OD
RETURN

PROC PrintInv(CHAR ARRAY a)
  BYTE i

  IF a(0)>0 THEN
    FOR i=1 TO a(0)
    DO
      Put(a(i)%$80)
    OD
  FI
RETURN

PROC Test(CHAR ARRAY in)
  CHAR ARRAY out(256)

  PrintInv("input  ")
  PrintF(" %S%E",in)

  Decode(in,out)
  PrintInv("decoded")
  PrintF(" %S%E%E",out)
RETURN

PROC Main()
  Test("http%3A%2F%2Ffoo%20bar%2F")
  Test("http%3A%2F%2Ffoo+bar%2F*_-.html")
RETURN


with AWS.URL;
with Ada.Text_IO; use Ada.Text_IO;
procedure Decode is
   Encoded : constant String := "http%3A%2F%2Ffoo%20bar%2F";
begin
   Put_Line (AWS.URL.Decode (Encoded));
end Decode;


# returns c decoded as a hex digit #
PROC hex value = ( CHAR c )INT: IF   c >= "0" AND c <= "9" THEN        ABS c - ABS "0"
                                ELIF c >= "A" AND c <= "F" THEN 10 + ( ABS c - ABS "A" )
                                ELSE                            10 + ( ABS c - ABS "a" )
                                FI;

# returns the URL encoded string decoded - minimal error handling #
PROC url decode = ( STRING encoded )STRING:
     BEGIN
         [ LWB encoded : UPB encoded ]CHAR result;
         INT result pos  := LWB encoded;
         INT pos         := LWB encoded;
         INT max pos     := UPB encoded;
         INT max encoded := max pos - 3;
         WHILE pos <= UPB encoded
         DO
             IF encoded[ pos ] /= "%" AND pos <= max encoded
             THEN
                 # not a coded character #
                 result[ result pos ] := encoded[ pos ];
                 pos +:= 1
             ELSE
                 # have an encoded character #
                 result[ result pos ] := REPR ( ( 16 * hex value( encoded[ pos + 1 ] ) )
                                              +        hex value( encoded[ pos + 2 ] )
                                             );
                 pos +:= 3
             FI;
             result pos +:= 1
         OD;
         result[ LWB result : result pos - 1 ]
     END # url decode # ;

# test the url decode procedure #
print( ( url decode( "http%3A%2F%2Ffoo%20bar%2F" ),                 newline ) );
print( ( url decode( "google.com/search?q=%60Abdu%27l-Bah%C3%A1" ), newline ) )


(de urlEncodeTooMuch (Str)
   (pack
      (mapcar
         '((C)
            (if (or (>= "9" C "0") (>= "Z" (uppc C) "A"))
               C
               (list '% (hex (char C))) ) )
         (chop Str) ) ) )


Protocols.HTTP.uri_encode( "http://foo bar/" );


[uri]::EscapeDataString('http://foo bar/')

http%3A%2F%2Ffoo%20bar%2F


import urllib
s = 'http://foo/bar/'
s = urllib.quote(s)


#lang racket
(require net/uri-codec)
(uri-encode "http://foo bar/")


AST URL decode "google.com/search?q=%60Abdu%27l-Bah%C3%A1"


print decode.url "http%3A%2F%2Ffoo%20bar%2F"
print decode.url "google.com/search?q=%60Abdu%27l-Bah%C3%A1"


encURL := "http%3A%2F%2Ffoo%20bar%2F"
SetFormat, Integer, hex
Loop Parse, encURL
   If A_LoopField = `%
      reading := 2, read := ""
   else if reading
   {
      read .= A_LoopField, --reading
      if not reading
         out .= Chr("0x" . read)
   }
   else out .= A_LoopField
MsgBox % out ; http://foo bar/


# syntax:
awk '
BEGIN {
    str = "http%3A%2F%2Ffoo%20bar%2F" # "http://foo bar/"
    printf("%s\n",str)
    len=length(str)
    for (i=1;i<=len;i++) {
      if ( substr(str,i,1) == "%") {
        L = substr(str,1,i-1) # chars to left of "%"
        M = substr(str,i+1,2) # 2 chars to right of "%"
        R = substr(str,i+3)   # chars to right of "%xx"
        str = sprintf("%s%c%s",L,hex2dec(M),R)
      }
    }
    printf("%s\n",str)
    exit(0)
}
function hex2dec(s,  num) {
    num = index("0123456789ABCDEF",toupper(substr(s,length(s)))) - 1
    sub(/.$/,"",s)
    return num + (length(s) ? 16*hex2dec(s) : 0)
} '


my $url = 'http://foo bar/';

say $url.subst(/<-alnum>/, *.ord.fmt("%%%02X"), :g);


  Dim URL As String = "http://foo bar/"
  URL = EncodeURLComponent(URL)
  Print(URL)


/* Rexx */
do
  call testcase
  say
  say RFC3986
  call testcase RFC3986
  say
  say HTML5
  call testcase HTML5
  say
  return
end
exit

/* -------------------------------------------------------------------------- */
encode:
procedure
do
  parse arg url, varn .
  parse upper var varn variation
  drop RFC3986 HTML5
  opts. = ''
  opts.RFC3986 = '-._~'
  opts.HTML5   = '-._*'

  rp = ''
  do while length(url) > 0
    parse var url tc +1 url
    select
      when datatype(tc, 'A') then do
        rp = rp || tc
        end
      when tc == ' ' then do
        if variation = HTML5 then
          rp = rp || '+'
        else
          rp = rp || '%' || c2x(tc)
        end
      otherwise do
        if pos(tc, opts.variation) > 0 then do
          rp = rp || tc
          end
        else do
          rp = rp || '%' || c2x(tc)
          end
        end
      end
    end

  return rp
end
exit

/* -------------------------------------------------------------------------- */
testcase:
procedure
do
  parse arg variation
  X = 0
  url. = ''
  X = X + 1; url.0 = X; url.X = 'http://foo bar/'
  X = X + 1; url.0 = X; url.X = 'mailto:"Ivan Aim" <[email protected]>'
  X = X + 1; url.0 = X; url.X = 'mailto:"Irma User" <[email protected]>'
  X = X + 1; url.0 = X; url.X = 'http://foo.bar.com/~user-name/_subdir/*~.html'

  do i_ = 1 to url.0
    say url.i_
    say encode(url.i_, variation)
    end i_

  return
end


require 'cgi'
puts CGI.escape("http://foo bar/").gsub("+", "%20")
# => "http%3A%2F%2Ffoo%20bar%2F"


FUNCTION Url_Decode$(url$)

    LOCAL result$

    SPLIT url$ BY "%" TO item$ SIZE total
    FOR x = 1 TO total-1
        result$ = result$ & CHR$(DEC(LEFT$(item$[x], 2))) & MID$(item$[x], 3)
    NEXT
    RETURN item$[0] & result$

END FUNCTION

PRINT Url_Decode$("http%3A%2F%2Ffoo%20bar%2F")
PRINT Url_Decode$("google.com/search?q=%60Abdu%27l-Bah%C3%A1")


      PRINT FNurldecode("http%3A%2F%2Ffoo%20bar%2F")
      END

      DEF FNurldecode(url$)
      LOCAL i%
      REPEAT
        i% = INSTR(url$, "%", i%+1)
        IF i% THEN
          url$ = LEFT$(url$,i%-1) + \
          \      CHR$EVAL("&"+FNupper(MID$(url$,i%+1,2))) + \
          \      MID$(url$,i%+3)
        ENDIF
      UNTIL i% = 0
      = url$

      DEF FNupper(A$)
      LOCAL A%,C%
      FOR A% = 1 TO LEN(A$)
        C% = ASCMID$(A$,A%)
        IF C% >= 97 IF C% <= 122 MID$(A$,A%,1) = CHR$(C%-32)
      NEXT
      = A$


(     ( decode
      =   decoded hexcode notencoded
        .   :?decoded
          &   whl
            ' ( @(!arg:?notencoded "%" (% %:?hexcode) ?arg)
              & !decoded !notencoded chr$(x2d$!hexcode):?decoded
              )
          & str$(!decoded !arg)
      )
    & out$(decode$http%3A%2F%2Ffoo%20bar%2F)
);


#include <stdio.h>
#include <string.h>

inline int ishex(int x)
{
	return	(x >= '0' && x <= '9')	||
		(x >= 'a' && x <= 'f')	||
		(x >= 'A' && x <= 'F');
}

int decode(const char *s, char *dec)
{
	char *o;
	const char *end = s + strlen(s);
	int c;

	for (o = dec; s <= end; o++) {
		c = *s++;
		if (c == '+') c = ' ';
		else if (c == '%' && (	!ishex(*s++)	||
					!ishex(*s++)	||
					!sscanf(s - 2, "%2x", &c)))
			return -1;

		if (dec) *o = c;
	}

	return o - dec;
}

int main()
{
	const char *url = "http%3A%2F%2ffoo+bar%2fabcd";
	char out[strlen(url) + 1];

	printf("length: %d\n", decode(url, 0));
	puts(decode(url, out) < 0 ? "bad string" : out);

	return 0;
}


urlIn$ = "http://foo bar/"

for i = 1 to len(urlIn$)
  a$ = mid$(urlIn$,i,1)
  if (a$ >= "0" and a$ <= "9") _
  or (a$ >= "A" and a$ <= "Z") _
  or (a$ >= "a" and a$ <= "z") then url$ = url$ + a$ else url$ = url$ + "%"+dechex$(asc(a$))
next i
print urlIn$;" -> ";url$


const INPUT: &str = "http://foo bar/";
const MAX_CHAR_VAL: u32 = std::char::MAX as u32;

fn main() {
    let mut buff = [0; 4];
    println!("{}", INPUT.chars()
        .map(|ch| {
            match ch as u32 {
                0 ..= 47 | 58 ..= 64 | 91 ..= 96 | 123 ..= MAX_CHAR_VAL => {
                    ch.encode_utf8(&mut buff);
                    buff[0..ch.len_utf8()].iter().map(|&byte| format!("%{:X}", byte)).collect::<String>()
                },
                _ => ch.to_string(),
            }
        })
        .collect::<String>()
    );
}


import java.net.{URLDecoder, URLEncoder}
import scala.compat.Platform.currentTime

object UrlCoded extends App {
  val original = """http://foo bar/"""
  val encoded: String = URLEncoder.encode(original, "UTF-8")

  assert(encoded == "http%3A%2F%2Ffoo+bar%2F", s"Original: $original not properly encoded: $encoded")

  val percentEncoding = encoded.replace("+", "%20")
  assert(percentEncoding == "http%3A%2F%2Ffoo%20bar%2F", s"Original: $original not properly percent-encoded: $percentEncoding")

  assert(URLDecoder.decode(encoded, "UTF-8") == URLDecoder.decode(percentEncoding, "UTF-8"))

  println(s"Successfully completed without errors. [total ${currentTime - executionStart} ms]")
}


$ include "seed7_05.s7i";
  include "encoding.s7i";

const proc: main is func
  begin
    writeln(toPercentEncoded("http://foo bar/"));
    writeln(toUrlEncoded("http://foo bar/"));
  end func;


func urlencode(str) {
    str.gsub!(%r"([^-A-Za-z0-9_.!~*'() ])", {|a| "%%%02X" % a.ord});
    str.gsub!(' ', '+');
    return str;
}

say urlencode('http://foo bar/');


using System;

namespace URLEncode
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Console.WriteLine(Decode("http%3A%2F%2Ffoo%20bar%2F"));
        }

        private static string Decode(string uri)
        {
            return Uri.UnescapeDataString(uri);
        }
    }
}


#include <string>
#include "Poco/URI.h"
#include <iostream>

int main( ) {
   std::string encoded( "http%3A%2F%2Ffoo%20bar%2F" ) ;
   std::string decoded ;
   Poco::URI::decode ( encoded , decoded ) ;
   std::cout << encoded << " is decoded: " << decoded << " !" << std::endl ;
   return 0 ;
}


USER>Write $ZConvert("http%3A%2F%2Ffoo%20bar%2F", "I", "URL")
http://foo bar/


# Encode all except "unreserved" characters; use UTF-8 for extended chars.
# See http://tools.ietf.org/html/rfc3986 §2.4 and §2.5
proc urlEncode {str} {
    set uStr [encoding convertto utf-8 $str]
    set chRE {[^-A-Za-z0-9._~\n]};		# Newline is special case!
    set replacement {%[format "%02X" [scan "\\\0" "%c"]]}
    return [string map {"\n" "%0A"} [subst [regsub -all $chRE $uStr $replacement]]]
}


$$ MODE TUSCRIPT
text="http://foo bar/"
BUILD S_TABLE spez_char="::>/:</::<%:"
spez_char=STRINGS (text,spez_char)
LOOP/CLEAR c=spez_char
c=ENCODE(c,hex),c=concat("%",c),spez_char=APPEND(spez_char,c)
ENDLOOP
url_encoded=SUBSTITUTE(text,spez_char,0,0,spez_char)
print "text:    ", text
PRINT "encoded: ", url_encoded


function urlencode
{
	typeset decoded=$1 encoded= rest= c=
	typeset rest2= bug='rest2=${rest}'

	if [[ -z ${BASH_VERSION} ]]; then
		# bug /usr/bin/sh HP-UX 11.00
		typeset _decoded='xyz%26xyz'
		rest="${_decoded#?}"
		c="${_decoded%%${rest}}"
		if (( ${#c} != 1 )); then
			typeset qm='????????????????????????????????????????????????????????????????????????'
			typeset bug='(( ${#rest} > 0 )) && typeset -L${#rest} rest2="${qm}" || rest2=${rest}'
		fi
	fi

	rest="${decoded#?}"
	eval ${bug}
	c="${decoded%%${rest2}}"
	decoded="${rest}"

	while [[ -n ${c} ]]; do
		case ${c} in
		[-a-zA-z0-9.])
			;;
		' ')
			c='+'
			;;
		*)
			c=$(printf "%%%02X" "'$c")
			;;
		esac

		encoded="${encoded}${c}"

		rest="${decoded#?}"
		eval ${bug}
		c="${decoded%%${rest2}}"
		decoded="${rest}"
	done

	if [[ -n ${BASH_VERSION:-} ]]; then
		\echo -E "${encoded}"
	else
		print -r -- "${encoded}"
	fi
}


Function UrlEncode(url)
	For i = 1 To Len(url)
		n = Asc(Mid(url,i,1))
		If (n >= 48 And n <= 57) Or (n >= 65 And n <= 90) _
			Or (n >= 97 And n <= 122) Then
			UrlEncode = UrlEncode & Mid(url,i,1)
		Else
			ChrHex = Hex(Asc(Mid(url,i,1)))
                        For j = 0 to (Len(ChrHex) / 2) - 1
			    UrlEncode = UrlEncode & "%" & Mid(ChrHex,(2*j) + 1,2)
                        Next
		End If
	Next
End Function

WScript.Echo UrlEncode("http://foo baré/")


(defun decode (string &key start)
  (assert (char= (char string start) #\%))
  (if (>= (length string) (+ start 3))
      (multiple-value-bind (code pos)
          (parse-integer string :start (1+ start) :end (+ start 3) :radix 16 :junk-allowed t)
        (if (= pos (+ start 3))
            (values (code-char code) pos)
            (values #\% (1+ start))))
      (values #\% (1+ start))))

(defun url-decode (url)
  (loop with start = 0
        for pos = (position #\% url :start start)
        collect (subseq url start pos) into chunks
        when pos
          collect (multiple-value-bind (decoded next) (decode url :start pos)
                    (setf start next)
                    (string decoded))
            into chunks
        while pos
        finally (return (apply #'concatenate 'string chunks))))

(url-decode "http%3A%2F%2Ffoo%20bar%2F")


require "uri"

puts URI.decode "http%3A%2F%2Ffoo%20bar%2F"
puts URI.decode "google.com/search?q=%60Abdu%27l-Bah%C3%A1"


import std.stdio, std.uri;

void main() {
    writeln(decodeComponent("http%3A%2F%2Ffoo%20bar%2F"));
}


import net.urllib
fn main() {
	println(urllib.query_escape("http://foo bar/"))
}


import "/fmt" for Fmt

var urlEncode = Fn.new { |url|
    var res = ""
    for (b in url.bytes) {
        if ((b >= 48 && b <= 57) || (b >= 65 && b <= 90) || (b >= 97 && b <= 122)) {
            res = res + String.fromByte(b)
        } else {
            res = res + Fmt.swrite("\%$2X", b)
        }
    }
    return res
}

var urls = [
    "http://foo bar/",
    "mailto:\"Ivan Aim\" <[email protected]>",
    "mailto:\"Irma User\" <[email protected]>",
    "http://foo.bar.com/~user-name/_subdir/*~.html"
]
for (url in urls) System.print(urlEncode.call(url))


code Text=12;
string 0;               \use zero-terminated strings

func Encode(S0);        \Encode URL string and return its address
char S0;
char HD, S1(80);        \BEWARE: very temporary string space returned
int  C, I, J;
[HD:= "0123456789ABCDEF"; \hex digits
I:= 0;  J:= 0;
repeat  C:= S0(I);  I:= I+1;
        if C>=^0 & C<=^9 ! C>=^A & C<=^Z ! C>=^a & C<=^z ! C=0
        then    [S1(J):= C;  J:= J+1]           \simply pass char to S1
        else    [S1(J):= ^%;  J:= J+1;          \encode char into S1
                 S1(J):= HD(C>>4);  J:= J+1;
                 S1(J):= HD(C&$0F); J:= J+1;
                ];
until   C=0;
return S1;
];

Text(0, Encode("http://foo bar/"))


sub encode_url$(s$, exclusions$, spaceplus)
    local res$, i, ch$

    for i=1 to len(s$)
        ch$ = mid$(s$, i, 1)
        if ch$ = " " and spaceplus then
            ch$ = "+"
        elsif not instr(esclusions$, ch$) and (ch$ < "0" or (ch$ > "9" and ch$ < "A") or (ch$ > "Z" and ch$ < "a") or  ch$ > "z") then
            res$ = res$ + "%"
            ch$ = upper$(hex$(asc(ch$)))
        end if
        res$ = res$ + ch$
    next i
    return res$
end sub

print encode_url$("http://foo bar/")


var CURL=Import("zklCurl");
CURL.urlEncode("http://foo bar/") //--> "http%3A%2F%2Ffoo%20bar%2F"


program URLEncoding;

{$APPTYPE CONSOLE}

uses IdURI;

begin
  Writeln(TIdURI.URLDecode('http%3A%2F%2Ffoo%20bar%2F'));
end.


IO.inspect URI.decode("http%3A%2F%2Ffoo%20bar%2F")
IO.inspect URI.decode("google.com/search?q=%60Abdu%27l-Bah%C3%A1")


34> http_uri:decode("http%3A%2F%2Ffoo%20bar%2F").
"http://foo bar/"


open System

let decode uri = Uri.UnescapeDataString(uri)

[<EntryPoint>]
let main argv =
    printfn "%s" (decode "http%3A%2F%2Ffoo%20bar%2F")
    0


USING: io kernel urls.encoding ;
IN: rosetta-code.url-decoding

"http%3A%2F%2Ffoo%20bar%2F"
"google.com/search?q=%60Abdu%27l-Bah%C3%A1"
[ url-decode print ] [email protected]


function urlDecode(data: String): AnsiString;
var
  ch: Char;
  pos, skip: Integer;

begin
  pos := 0;
  skip := 0;
  Result := '';

  for ch in data do begin
    if skip = 0 then begin
      if (ch = '%') and (pos < data.length -2) then begin
        skip := 2;
        Result := Result + AnsiChar(Hex2Dec('$' + data[pos+2] + data[pos+3]));

      end else begin
        Result := Result + ch;
      end;

    end else begin
      skip := skip - 1;
    end;
    pos := pos +1;
  end;
end;


Const alphanum = "0123456789abcdefghijklmnopqrstuvwxyz"

Function ToDecimal (cadena As String, base_ As Uinteger) As Uinteger
    Dim As Uinteger i, n, result = 0
    Dim As Uinteger inlength = Len(cadena)

    For i = 1 To inlength
        n = Instr(alphanum, Mid(Lcase(cadena),i,1)) - 1
        n *= (base_^(inlength-i))
        result += n
    Next
    Return result
End Function

Function url2string(cadena As String) As String
    Dim As String c, nc, res

    For j As Integer = 1 To Len(cadena)
        c = Mid(cadena, j, 1)
        If c = "%" Then
            nc = Chr(ToDecimal((Mid(cadena, j+1, 2)), 16))
            res &= nc
            j += 2
        Else
            res &= c
        End If
    Next j
    Return res
End Function

Dim As String URL = "http%3A%2F%2Ffoo%20bar%2F"

Print "Supplied URL '"; URL; "'"
Print "URL decoding '"; url2string(URL); "'"

URL = "google.com/search?q=%60Abdu%27l-Bah%C3%A1"
Print !"\nSupplied URL '"; URL; "'"
Print "URL decoding '"; url2string(URL); "'"
Sleep


package main

import (
	"fmt"
	"log"
	"net/url"
)

func main() {
	for _, escaped := range []string{
		"http%3A%2F%2Ffoo%20bar%2F",
		"google.com/search?q=%60Abdu%27l-Bah%C3%A1",
	} {
		u, err := url.QueryUnescape(escaped)
		if err != nil {
			log.Println(err)
			continue
		}
		fmt.Println(u)
	}
}


assert URLDecoder.decode('http%3A%2F%2Ffoo%20bar%2F') == 'http://foo bar/'


import qualified Data.Char as Char

urlDecode :: String -> Maybe String
urlDecode [] = Just []
urlDecode ('%':xs) =
  case xs of
    (a:b:xss) ->
      urlDecode xss
      >>= return . ((Char.chr . read $ "0x" ++ [a,b]) :)
    _ -> Nothing
urlDecode ('+':xs) = urlDecode xs >>= return . (' ' :)
urlDecode (x:xs) = urlDecode xs >>= return . (x :)

main :: IO ()
main = putStrLn . maybe "Bad decode" id $ urlDecode "http%3A%2F%2Ffoo%20bar%2F"


link hexcvt

procedure main()
ue := "http%3A%2F%2Ffoo%20bar%2F"
ud := decodeURL(ue) | stop("Improperly encoded string ",image(ue))
write("encoded = ",image(ue))
write("decoded = ",image(ue))
end

procedure decodeURL(s)              #: decode URL/URI encoded data
static de
initial {                           # build lookup table for everything
  de := table()
  every de[hexstring(ord(c := !string(&ascii)),2)] := c
  }

c := ""
s ? until pos(0) do                 # decode every %xx or fail
   c ||:= if ="%" then \de[move(2)] | fail
   else move(1)
return c
end


require'strings convert'
urldecode=: rplc&(~.,/;"_1&a."2(,:tolower)'%',.toupper hfd i.#a.)


import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

public class Main
{
    public static void main(String[] args) throws UnsupportedEncodingException
    {
        String encoded = "http%3A%2F%2Ffoo%20bar%2F";
        String normal = URLDecoder.decode(encoded, "utf-8");
        System.out.println(normal);
    }
}


# Emit . and stop as soon as "condition" is true.
def until(condition; next):
  def u: if condition then . else (next|u) end;
  u;

def url_decode:
  # The helper function converts the input string written in the given
  # "base" to an integer
  def to_i(base):
    explode
    | reverse
    | map(if 65 <= . and . <= 90 then . + 32  else . end)   # downcase
    | map(if . > 96  then . - 87 else . - 48 end)  # "a" ~ 97 => 10 ~ 87
    | reduce .[] as $c
        # base: [power, ans]
        ([1,0]; (.[0] * base) as $b | [$b, .[1] + (.[0] * $c)]) | .[1];

  .  as $in
  | length as $length
  | [0, ""]  # i, answer
  | until ( .[0] >= $length;
      .[0] as $i
      |  if $in[$i:$i+1] == "%"
         then [ $i + 3, .[1] + ([$in[$i+1:$i+3] | to_i(16)] | implode) ]
         else [ $i + 1, .[1] + $in[$i:$i+1] ]
         end)
  | .[1];  # answer


using URIParser

enc = "http%3A%2F%2Ffoo%20bar%2F"

dcd = unescape(enc)

println(enc, " => ", dcd)


// version 1.1.2

import java.net.URLDecoder

fun main(args: Array<String>) {
    val encoded = arrayOf("http%3A%2F%2Ffoo%20bar%2F", "google.com/search?q=%60Abdu%27l-Bah%C3%A1")
    for (e in encoded) println(URLDecoder.decode(e, "UTF-8"))
}


url_decode()
{
        decode="${*//+/ }"
        eval print -r -- "\$'${decode//'%'@(??)/'\'x\1"'\$'"}'"  2>/dev/null
}

url_decode "http%3A%2F%2Ffoo%20bar%2F"
url_decode "google.com/search?q=%60Abdu%27l-Bah%C3%A1"


1) define a new javascript primitive:
{script
  LAMBDATALK.DICT['decodeURIComponent'] = function() {
    return decodeURIComponent( arguments[0].trim() );
  };
}

2) and use it:
{decodeURIComponent http%3A%2F%2Ffoo%20bar%2F}
-> http://foo bar/


    dim lookUp$( 256)

    for i =0 to 256
        lookUp$( i) ="%" +dechex$( i)
    next i

    url$ ="http%3A%2F%2Ffoo%20bar%2F"

    print "Supplied URL '"; url$; "'"
    print "As string    '"; url2string$( url$); "'"

    end

function url2string$( i$)
    for j =1 to len( i$)
        c$ =mid$( i$, j, 1)
        if c$ ="%" then
            nc$         =chr$( hexdec( mid$( i$, j +1, 2)))
            url2string$ =url2string$ +nc$
            j =j +2
        else
            url2string$ =url2string$ +c$
        end if
    next j
end function


----------------------------------------
-- URL decodes a string
-- @param {string} str
-- @return {string}
----------------------------------------
on urldecode (str)
    res = ""
    ba = bytearray()
    len = str.length
    repeat with i = 1 to len
        c = str.char[i]
        if (c = "%") then
            -- fastest hex-to-dec conversion hack based on Lingo's rgb object
            ba.writeInt8(rgb(str.char[i+1..i+2]).blue)
            i = i + 2
        else if (c = "+") then
            ba.writeInt8(32)
        else
            ba.writeInt8(chartonum(c))
        end if
    end repeat
    ba.position = 1
    return ba.readRawString(ba.length)
end


put urlDecode("http%3A%2F%2Ffoo%20bar%2F") & cr & \
    urlDecode("google.com/search?q=%60Abdu%27l-Bah%C3%A1")


function decodeChar(hex)
	return string.char(tonumber(hex,16))
end

function decodeString(str)
	local output, t = string.gsub(str,"%%(%x%x)",decodeChar)
	return output
end

-- will print "http://foo bar/"
print(decodeString("http%3A%2F%2Ffoo%20bar%2F"))


Module CheckIt {
      Function decodeUrl$(a$) {
            DIM a$()
            a$()=Piece$(a$, "%")
            if len(a$())=1 then =str$(a$):exit
            k=each(a$(),2)
            \\ convert to one byte per character using str$(string)
            acc$=str$(a$(0))
            While k {
                        \\ chr$() convert to UTF16LE
                        \\ str$()  convert to ANSI using locale (can be 1033 we can set it before as Locale 1033)
                        \\ so chr$(0x93) give 0x201C
                        \\ str$(chr$(0x93)) return one byte 93 in ANSI as string of one byte length
                        \\ numbers are for UTF-8 so we have to preserve them
                  acc$+=str$(Chr$(Eval("0x"+left$(a$(k^),2)))+Mid$(a$(k^),3))
            }
            =acc$
      }
      \\ decode from utf8
      final$=DecodeUrl$("google.com/search?q=%60Abdu%27l-Bah%C3%A1")
      Print string$(final$ as utf8dec)="google.com/search?q=`Abdu'l-Bahá"
      final$=DecodeUrl$("http%3A%2F%2Ffoo%20bar%2F")
      Print string$(final$ as utf8dec)="http://foo bar/"
}
CheckIt


URLDecoding[url_] :=
 StringReplace[url, "%" ~~ x_ ~~ y_ :> FromDigits[x ~~ y, 16]] //.
  StringExpression[x___, Longest[n__Integer], y___] :>
   StringExpression[x, FromCharacterCode[{n}, "UTF8"], y]


function u = urldecoding(s)
    u = '';
    k = 1;
    while k<=length(s)
        if s(k) == '%' && k+2 <= length(s)
            u = sprintf('%s%c', u, char(hex2dec(s((k+1):(k+2)))));
            k = k + 3;
        else
            u = sprintf('%s%c', u, s(k));
            k = k + 1;
        end
    end
end


/* NetRexx */
options replace format comments java crossref savelog symbols nobinary

url = [ -
  'http%3A%2F%2Ffoo%20bar%2F', -
  'mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E', -
  '%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E' -
  ]

loop u_ = 0 to url.length - 1
  say url[u_]
  say DecodeURL(url[u_])
  say
  end u_

return

method DecodeURL(arg) public static

  Parse arg encoded
  decoded = ''
  PCT = '%'

  loop label e_ while encoded.length() > 0
    parse encoded head (PCT) +1 code +2 tail
    decoded = decoded || head
    select
      when code.strip('T').length() = 2 & code.datatype('X') then do
        code = code.x2c()
        decoded = decoded || code
        end
      when code.strip('T').length() \= 0 then do
        decoded = decoded || PCT
        tail = code || tail
        end
      otherwise do
        nop
        end
      end
    encoded = tail
    end e_

  return decoded


;; universal decoder, works for ASCII and UTF-8
;; (source http://www.newlisp.org/index.cgi?page=Code_Snippets)
(define (url-decode url (opt nil))
  (if opt (replace "+" url " "))
  (replace "%([0-9a-f][0-9a-f])" url (pack "b" (int $1 0 16)) 1))

(url-decode "http%3A%2F%2Ffoo%20bar%2F")


import cgi

echo decodeUrl("http%3A%2F%2Ffoo%20bar%2F")


MODULE URLDecoding;
IMPORT
  URI := URI:String,
  Out := NPCT:Console;
BEGIN
  Out.String(URI.Unescape("http%3A%2F%2Ffoo%20bar%2F"));Out.Ln;
  Out.String(URI.Unescape("google.com/search?q=%60Abdu%27l-Bah%C3%A1"));Out.Ln;
END URLDecoding.


class UrlDecode {
  function : Main(args : String[]) ~ Nil {
    Net.UrlUtility->Decode("http%3A%2F%2Ffoo%20bar%2F")->PrintLine();
  }
}


NSString *encoded = @"http%3A%2F%2Ffoo%20bar%2F";
NSString *normal = [encoded stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", normal);


$ ocaml
# #use "topfind";;
# #require "netstring";;

# Netencoding.Url.decode "http%3A%2F%2Ffoo%20bar%2F" ;;
- : string = "http://foo bar/"


/* Rexx */
  X = 0
  url. = ''
  X = X + 1; url.0 = X; url.X = 'http%3A%2F%2Ffoo%20bar%2F'
  X = X + 1; url.0 = X; url.X = 'mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E'
  X = X + 1; url.0 = X; url.X = '%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E'

  Do u_ = 1 to url.0
    Say url.u_
    Say DecodeURL(url.u_)
    Say
    End u_

Exit

DecodeURL: Procedure

  Parse Arg encoded
  decoded = ''
  PCT = '%'

  Do label e_ while encoded~length() > 0
    Parse Var encoded head (PCT) +1 code +2 tail
    decoded = decoded || head
    Select
      when code~strip('T')~length() = 2 & code~datatype('X') then Do
        code = code~x2c()
        decoded = decoded || code
        End
      when code~strip('T')~length() \= 0 then Do
        decoded = decoded || PCT
        tail = code || tail
        End
      otherwise
        Nop
      End
    encoded = tail
    End e_

  Return decoded


sub urldecode {
    my $s = shift;
    $s =~ tr/\+/ /;
    $s =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/eg;
    return $s;
}

print urldecode('http%3A%2F%2Ffoo+bar%2F')."\n";


--
-- demo\rosetta\decode_url.exw
-- ===========================
--
with javascript_semantics
function decode_url(string s)
integer skip = 0
string res = ""
    for i=1 to length(s) do
        if skip then
            skip -= 1
        else
            integer ch = s[i]
            if ch='%' then
                sequence scanres = {}
                if i+2<=length(s) then
                    scanres = scanf("#"&s[i+1..i+2],"%x")
                end if
                if length(scanres)!=1 then
                    return "decode error"
                end if
                skip = 2
                ch = scanres[1][1]
            elsif ch='+' then
                ch = ' '
            end if
            res &= ch
        end if
    end for
    return res
end function

printf(1,"%s\n",{decode_url("http%3A%2F%2Ffoo%20bar%2F")})
printf(1,"%s\n",{decode_url("google.com/search?q=%60Abdu%27l-Bah%C3%A1")})

{} = wait_key()


<?php
$encoded = "http%3A%2F%2Ffoo%20bar%2F";
$unencoded = rawurldecode($encoded);
echo "The unencoded string is $unencoded !\n";
?>


: (ht:Pack (chop "http%3A%2F%2Ffoo%20bar%2F") T)
-> "http://foo bar/"


void main()
{
    array encoded_urls = ({
        "http%3A%2F%2Ffoo%20bar%2F",
        "google.com/search?q=%60Abdu%27l-Bah%C3%A1"
    });

    foreach(encoded_urls, string url) {
        string decoded = Protocols.HTTP.uri_decode( url );
        write( string_to_utf8(decoded) +"\n" ); // Assume sink does UTF8
    }
}


URL$ = URLDecoder("http%3A%2F%2Ffoo%20bar%2F")

Debug URL$  ; http://foo bar/


#Python 2.X
import urllib
print urllib.unquote("http%3A%2F%2Ffoo%20bar%2F")
#Python 3.5+
from urllib.parse import unquote
print(unquote('http%3A%2F%2Ffoo%20bar%2F'))


#lang racket
(require net/uri-codec)
(uri-decode "http%3A%2F%2Ffoo%20bar%2F")


my @urls = < http%3A%2F%2Ffoo%20bar%2F
             google.com/search?q=%60Abdu%27l-Bah%C3%A1 >;

say .subst( :g,
    / [ '%' ( <:hexdigit> ** 2 ) ]+ / ,
    { Blob.new((:16(~$_) for $0)).decode }
    ) for @urls;


>> dehex "http%3A%2F%2Ffoo%20bar%2F"
== "http://foo bar/"
>> dehex "google.com/search?q=%60Abdu%27l-Bah%C3%A1"
== "google.com/search?q=`Abdu'l-Bahá"


create buffer 32000 allot

{{
  create bit 5 allot
  : extract  ( $c-$a ) drop @+ bit ! @+ bit 1+ ! bit ;
  : render   ( $c-$n )
    dup '+ = [ drop 32 ] ifTrue
    dup 13 = [ drop 32 ] ifTrue
    dup 10 = [ drop 32 ] ifTrue
    dup '% = [ extract hex toNumber decimal ] ifTrue ;
  : <decode> (  $-$  ) repeat @+ 0; render ^buffer'add again ;
---reveal---
  : decode   (  $-   ) buffer ^buffer'set <decode> drop ;
}}

"http%3A%2F%2Ffoo%20bar%2F" decode buffer puts


/* Rexx */

Do
  X = 0
  url. = ''
  X = X + 1; url.0 = X; url.X = 'http%3A%2F%2Ffoo%20bar%2F'
  X = X + 1; url.0 = X; url.X = 'mailto%3A%22Ivan%20Aim%22%20%3Civan%2Eaim%40email%2Ecom%3E'
  X = X + 1; url.0 = X; url.X = '%6D%61%69%6C%74%6F%3A%22%49%72%6D%61%20%55%73%65%72%22%20%3C%69%72%6D%61%2E%75%73%65%72%40%6D%61%69%6C%2E%63%6F%6D%3E'

  Do u_ = 1 to url.0
    Say url.u_
    Say DecodeURL(url.u_)
    Say
    End u_

  Return
End
Exit

DecodeURL:
Procedure
Do
  Parse Arg encoded
  decoded = ''
  PCT = '%'

  Do while length(encoded) > 0
    Parse Var encoded head (PCT) +1 code +2 tail
    decoded = decoded || head
    Select
      When length(strip(code, 'T')) = 2 & datatype(code, 'X') then Do
        code = x2c(code)
        decoded = decoded || code
        End
      When length(strip(code, 'T')) \= 0 then Do
        decoded = decoded || PCT
        tail = code || tail
        End
      Otherwise Do
        Nop
        End
      End
    encoded = tail
    End

  Return decoded
End
Exit


require 'cgi'
puts CGI.unescape("http%3A%2F%2Ffoo%20bar%2F")
# => "http://foo bar/"


const INPUT1: &str = "http%3A%2F%2Ffoo%20bar%2F";
const INPUT2: &str = "google.com/search?q=%60Abdu%27l-Bah%C3%A1";

fn append_frag(text: &mut String, frag: &mut String) {
    if !frag.is_empty() {
        let encoded = frag.chars()
            .collect::<Vec<char>>()
            .chunks(2)
            .map(|ch| {
                u8::from_str_radix(&ch.iter().collect::<String>(), 16).unwrap()
            }).collect::<Vec<u8>>();
        text.push_str(&std::str::from_utf8(&encoded).unwrap());
        frag.clear();
    }
}

fn decode(text: &str) -> String {
    let mut output = String::new();
    let mut encoded_ch = String::new();
    let mut iter = text.chars();
    while let Some(ch) = iter.next() {
        if ch == '%' {
            encoded_ch.push_str(&format!("{}{}", iter.next().unwrap(), iter.next().unwrap()));
        } else {
            append_frag(&mut output, &mut encoded_ch);
            output.push(ch);
        }
    }
    append_frag(&mut output, &mut encoded_ch);
    output
}

fn main() {
    println!("{}", decode(INPUT1));
    println!("{}", decode(INPUT2));
}


import java.net.{URLDecoder, URLEncoder}
import scala.compat.Platform.currentTime

object UrlCoded extends App {
  val original = """http://foo bar/"""
  val encoded: String = URLEncoder.encode(original, "UTF-8")

  assert(encoded == "http%3A%2F%2Ffoo+bar%2F", s"Original: $original not properly encoded: $encoded")

  val percentEncoding = encoded.replace("+", "%20")
  assert(percentEncoding == "http%3A%2F%2Ffoo%20bar%2F", s"Original: $original not properly percent-encoded: $percentEncoding")

  assert(URLDecoder.decode(encoded, "UTF-8") == URLDecoder.decode(percentEncoding, "UTF-8"))

  println(s"Successfully completed without errors. [total ${currentTime - executionStart} ms]")
}


$ include "seed7_05.s7i";
  include "encoding.s7i";

const proc: main is func
  begin
    writeln(fromPercentEncoded("http%3A%2F%2Ffoo%20bar%2F"));
    writeln(fromUrlEncoded("http%3A%2F%2Ffoo+bar%2F"));
  end func;


func urldecode(str) {
    str.gsub!('+', ' ');
    str.gsub!(/\%([A-Fa-f0-9]{2})/, {|a| 'C'.pack(a.hex)});
    return str;
}

say urldecode('http%3A%2F%2Ffoo+bar%2F');  # => "http://foo bar/"


import Foundation

let encoded = "http%3A%2F%2Ffoo%20bar%2F"
if let normal = encoded.stringByReplacingPercentEscapesUsingEncoding(NSUTF8StringEncoding) {
  println(normal)
}


proc urlDecode {str} {
    set specialMap {"[" "%5B" "]" "%5D"}
    set seqRE {%([0-9a-fA-F]{2})}
    set replacement {[format "%c" [scan "\1" "%2x"]]}
    set modStr [regsub -all $seqRE [string map $specialMap $str] $replacement]
    return [encoding convertfrom utf-8 [subst -nobackslash -novariable $modStr]]
}


$$ MODE TUSCRIPT
url_encoded="http%3A%2F%2Ffoo%20bar%2F"
BUILD S_TABLE hex=":%><:><2<>2<%:"
hex=STRINGS (url_encoded,hex), hex=SPLIT(hex)
hex=DECODE (hex,hex)
url_decoded=SUBSTITUTE(url_encoded,":%><2<>2<%:",0,0,hex)
PRINT "encoded: ", url_encoded
PRINT "decoded: ", url_decoded


Function RegExTest(str,patrn)
    Dim regEx
    Set regEx = New RegExp
    regEx.IgnoreCase = True
    regEx.Pattern = patrn
    RegExTest = regEx.Test(str)
End Function

Function URLDecode(sStr)
    Dim str,code,a0
    str=""
    code=sStr
    code=Replace(code,"+"," ")
    While len(code)>0
        If InStr(code,"%")>0 Then
            str = str & Mid(code,1,InStr(code,"%")-1)
            code = Mid(code,InStr(code,"%"))
            a0 = UCase(Mid(code,2,1))
            If a0="U" And RegExTest(code,"^%u[0-9A-F]{4}") Then
                str = str & ChrW((Int("&H" & Mid(code,3,4))))
                code = Mid(code,7)
            ElseIf a0="E" And RegExTest(code,"^(%[0-9A-F]{2}){3}") Then
                str = str & ChrW((Int("&H" & Mid(code,2,2)) And 15) * 4096 + (Int("&H" & Mid(code,5,2)) And 63) * 64 + (Int("&H" & Mid(code,8,2)) And 63))
                code = Mid(code,10)
            ElseIf a0>="C" And a0<="D" And RegExTest(code,"^(%[0-9A-F]{2}){2}") Then
                str = str & ChrW((Int("&H" & Mid(code,2,2)) And 3) * 64 + (Int("&H" & Mid(code,5,2)) And 63))
                code = Mid(code,7)
            ElseIf (a0<="B" Or a0="F") And RegExTest(code,"^%[0-9A-F]{2}") Then
                str = str & Chr(Int("&H" & Mid(code,2,2)))
                code = Mid(code,4)
            Else
                str = str & "%"
                code = Mid(code,2)
            End If
        Else
            str = str & code
            code = ""
        End If
    Wend
    URLDecode = str
End Function

url = "http%3A%2F%2Ffoo%20bar%C3%A8%2F"
WScript.Echo "Encoded URL: " & url & vbCrLf &_
	"Decoded URL: " & UrlDecode(url)


import net.urllib
fn main() {
	for escaped in [
		"http%3A%2F%2Ffoo%20bar%2F",
		"google.com/search?q=%60Abdu%27l-Bah%C3%A1",
     ] {
		u := urllib.query_unescape(escaped)?
		println(u)
	}
}


import "/fmt" for Conv

var urlDecode = Fn.new { |enc|
    var res = ""
    var i = 0
    while (i < enc.count) {
        var c = enc[i]
        if (c == "\%") {
            var b = Conv.atoi(enc[i+1..i+2], 16)
            res = res + String.fromByte(b)
            i = i + 3
        } else {
            res = res + c
            i = i + 1
        }
    }
    return res
}

// We need to escape % characters in Wren as % is otherwise used for string interpolation.
var encs = [
    "http\%3A\%2F\%2Ffoo\%20bar\%2F",
    "google.com/search?q=\%60Abdu\%27l-Bah\%C3\%A1"
]
for (enc in encs)System.print(urlDecode.call(enc))


code Text=12;
string 0;               \use zero-terminated strings

func Decode(S0);        \Decode URL string and return its address
char S0;
char S1(80);            \BEWARE: very temporary string space returned
int  C, N, I, J;
[I:= 0;  J:= 0;
repeat  C:= S0(I);  I:= I+1;                    \get char
        if C=^% then                            \convert hex to char
                [C:= S0(I);  I:= I+1;
                if C>=^a then C:= C & ~$20;     \convert to uppercase
                N:= C - (if C<=^9 then ^0 else ^A-10);
                C:= S0(I);  I:= I+1;
                if C>=^a then C:= C & ~$20;
                C:= N*16 + C - (if C<=^9 then ^0 else ^A-10);
                ];
        S1(J):= C;  J:= J+1;                    \put char in output string
until   C=0;
return S1;
];

Text(0, Decode("http%3A%2F%2Ffoo%20bar%2f"))


sub decode_url$(s$)
    local res$, ch$

    while(s$ <> "")
        ch$ = left$(s$, 1)
        if ch$ = "%" then
            ch$ = chr$(dec(mid$(s$, 2, 2)))
            s$ = right$(s$, len(s$) - 3)
        else
            if ch$ = "+" ch$ = " "
            s$ = right$(s$, len(s$) - 1)
	endif
        res$ = res$ + ch$
    wend
    return res$
end sub

print decode_url$("http%3A%2F%2Ffoo%20bar%2F")
print decode_url$("google.com/search?q=%60Abdu%27l-Bah%C3%A1")


"http%3A%2F%2Ffoo%20bar%2F".pump(String,  // push each char through these fcns:
   fcn(c){ if(c=="%") return(Void.Read,2); return(Void.Skip,c) },// %-->read 2 chars else pass through
   fcn(_,b,c){ (b+c).toInt(16).toChar() })  // "%" (ignored)  "3"+"1"-->0x31-->"1"


with Ada.Text_IO;

with AWS.URL;
with AWS.Parameters;
with AWS.Containers.Tables;

procedure URL_Parser is

   procedure Parse (URL : in String) is

      use AWS.URL, Ada.Text_IO;
      use AWS.Containers.Tables;

      procedure Put_Cond (Item     : in String;
                          Value    : in String;
                          When_Not : in String := "") is
      begin
         if Value /= When_Not then
            Put ("  ");  Put (Item);  Put_Line (Value);
         end if;
      end Put_Cond;

      Obj  : Object;
      List : Table_Type;
   begin
      Put_Line ("Parsing " & URL);

      Obj  := Parse (URL);
      List := Table_Type (AWS.Parameters.List'(AWS.URL.Parameters (Obj)));

      Put_Cond ("Scheme:    ", Protocol_Name (Obj));
      Put_Cond ("Domain:    ", Host     (Obj));
      Put_Cond ("Port:      ", Port     (Obj), When_Not => "0");
      Put_Cond ("Path:      ", Path     (Obj));
      Put_Cond ("File:      ", File     (Obj));
      Put_Cond ("Query:     ", Query    (Obj));
      Put_Cond ("Fragment:  ", Fragment (Obj));
      Put_Cond ("User:      ", User     (Obj));
      Put_Cond ("Password:  ", Password (Obj));

      if List.Count /= 0 then
         Put_Line ("  Parameters:");
      end if;
      for Index in 1 .. List.Count loop
         Put ("    "); Put (Get_Name  (List, N => Index));
         Put ("    "); Put ("'" & Get_Value (List, N => Index) & "'");
         New_Line;
      end loop;
      New_Line;
   end Parse;

begin
   Parse ("foo://example.com:8042/over/there?name=ferret#nose");
   Parse ("urn:example:animal:ferret:nose");
   Parse ("jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true");
   Parse ("ftp://ftp.is.co.za/rfc/rfc1808.txt");
   Parse ("http://www.ietf.org/rfc/rfc2396.txt#header1");
   Parse ("ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two");
   Parse ("mailto:[email protected]");
   Parse ("news:comp.infosystems.www.servers.unix");
   Parse ("tel:+1-816-555-1212");
   Parse ("telnet://192.0.2.16:80/");
   Parse ("urn:oasis:names:specification:docbook:dtd:xml:4.1.2");
   Parse ("ssh://[email protected]");
   Parse ("https://bob:[email protected]/place");
   Parse ("http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64");
end URL_Parser;


PR read "uriParser.a68" PR

PROC test uri parser = ( STRING uri )VOID:
     BEGIN
         URI result := parse uri( uri );
         print( ( uri, ":", newline ) );
         IF NOT ok OF result
         THEN
             # the parse failed #
             print( ( "    ", error OF result, newline ) )
         ELSE
             # parsed OK #
             print(                                    ( "      scheme: ",      scheme OF result, newline ) );
             IF   userinfo OF result /= "" THEN print( ( "    userinfo: ",    userinfo OF result, newline ) ) FI;
             IF       host OF result /= "" THEN print( ( "        host: ",        host OF result, newline ) ) FI;
             IF       port OF result /= "" THEN print( ( "        port: ",        port OF result, newline ) ) FI;
             IF       path OF result /= "" THEN print( ( "        path: ",        path OF result, newline ) ) FI;
             IF      query OF result /= "" THEN print( ( "       query: ",       query OF result, newline ) ) FI;
             IF fragment id OF result /= "" THEN print( ( " fragment id: ", fragment id OF result, newline ) ) FI
         FI;
         print( ( newline ) )
     END # test uri parser # ;

BEGIN test uri parser( "foo://example.com:8042/over/there?name=ferret#nose"                      )
    ; test uri parser( "urn:example:animal:ferret:nose"                                          )
    ; test uri parser( "jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true" )
    ; test uri parser( "ftp://ftp.is.co.za/rfc/rfc1808.txt"                                      )
    ; test uri parser( "http://www.ietf.org/rfc/rfc2396.txt#header1"                             )
    ; test uri parser( "ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two"               )
    ; test uri parser( "mailto:[email protected]"                                             )
    ; test uri parser( "news:comp.infosystems.www.servers.unix"                                  )
    ; test uri parser( "tel:+1-816-555-1212"                                                     )
    ; test uri parser( "telnet://192.0.2.16:80/"                                                 )
    ; test uri parser( "urn:oasis:names:specification:docbook:dtd:xml:4.1.2"                     )
    ; test uri parser( "ssh://[email protected]"                                                 )
    ; test uri parser( "https://bob:[email protected]/place"                                      )
    ; test uri parser( "http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64"           )
END


use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later
use framework "Foundation"

on parseURLString(URLString)
    set output to {URLString}
    set indent to tab & "• "
    set componentsObject to current application's class "NSURLComponents"'s componentsWithString:(URLString)
    repeat with thisKey in {"scheme", "user", "password", "host", "port", "path", "query", "fragment"}
        set thisValue to (componentsObject's valueForKey:(thisKey))
        if (thisValue is not missing value) then set end of output to indent & thisKey & (" = " & thisValue)
    end repeat

    return join(output, linefeed)
end parseURLString

on join(listOfText, delimiter)
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to delimiter
    set output to listOfText as text
    set AppleScript's text item delimiters to astid
    return output
end join

-- Test code:
local output, URLString
set output to {}
repeat with URLString in {"foo://example.com:8042/over/there?name=ferret#nose", ¬
    "urn:example:animal:ferret:nose", ¬
    "jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true", ¬
    "ftp://ftp.is.co.za/rfc/rfc1808.txt", ¬
    "http://www.ietf.org/rfc/rfc2396.txt#header1", ¬
    "ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two", ¬
    "mailto:[email protected]", ¬
    "news:comp.infosystems.www.servers.unix", ¬
    "tel:+1-816-555-1212", ¬
    "telnet://192.0.2.16:80/", ¬
    "urn:oasis:names:specification:docbook:dtd:xml:4.1.2", ¬
    "http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64"}
    set end of output to parseURLString(URLString's contents)
end repeat

return join(output, linefeed & linefeed)


using System;

namespace RosettaUrlParse
{
    class Program
    {
        static void ParseUrl(string url)
        {
            var u = new Uri(url);
            Console.WriteLine("URL:         {0}", u.AbsoluteUri);
            Console.WriteLine("Scheme:      {0}", u.Scheme);
            Console.WriteLine("Host:        {0}", u.DnsSafeHost);
            Console.WriteLine("Port:        {0}", u.Port);
            Console.WriteLine("Path:        {0}", u.LocalPath);
            Console.WriteLine("Query:       {0}", u.Query);
            Console.WriteLine("Fragment:    {0}", u.Fragment);
            Console.WriteLine();
        }
        static void Main(string[] args)
        {
            ParseUrl("foo://example.com:8042/over/there?name=ferret#nose");
            ParseUrl("urn:example:animal:ferret:nose");
            ParseUrl("jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true");
            ParseUrl("ftp://ftp.is.co.za/rfc/rfc1808.txt");
            ParseUrl("http://www.ietf.org/rfc/rfc2396.txt#header1");
            ParseUrl("ldap://[2001:db8::7]/c=GB?objectClass?one");
            ParseUrl("mailto:[email protected]");
            ParseUrl("news:comp.infosystems.www.servers.unix");
            ParseUrl("tel:+1-816-555-1212");
            ParseUrl("telnet://192.0.2.16:80/");
            ParseUrl("urn:oasis:names:specification:docbook:dtd:xml:4.1.2");
        }
    }
}


require "uri"

examples = ["foo://example.com:8042/over/there?name=ferret#nose",
            "urn:example:animal:ferret:nose",
            "jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true",
            "ftp://ftp.is.co.za/rfc/rfc1808.txt",
            "http://www.ietf.org/rfc/rfc2396.txt#header1",
            "ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
            "mailto:[email protected]",
            "news:comp.infosystems.www.servers.unix",
            "tel:+1-816-555-1212",
            "telnet://192.0.2.16:80/",
            "urn:oasis:names:specification:docbook:dtd:xml:4.1.2",
            "https://bob:[email protected][::1]/place?a=1&b=2%202"]

examples.each do |example|
    puts "Parsing \"#{example}\":"
    url = URI.parse example
    {% for name in ["scheme", "host", "hostname", "port", "path", "userinfo",
                    "user", "password", "fragment", "query"] %}
        unless url.{{name.id}}.nil?
            puts "    {{name.id}}: \"#{url.{{name.id}}}\""
        end
    {% end %}
    unless url.query_params.empty?
        puts "    query_params:"
        url.query_params.each do |k, v|
            puts "        #{k}: \"#{v}\""
        end
    end
    puts
end


test_cases = [
  "foo://example.com:8042/over/there?name=ferret#nose",
  "urn:example:animal:ferret:nose",
  "jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true",
  "ftp://ftp.is.co.za/rfc/rfc1808.txt",
  "http://www.ietf.org/rfc/rfc2396.txt#header1",
  "ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
  "mailto:[email protected]",
  "news:comp.infosystems.www.servers.unix",
  "tel:+1-816-555-1212",
  "telnet://192.0.2.16:80/",
  "urn:oasis:names:specification:docbook:dtd:xml:4.1.2",
  "ssh://[email protected]",
  "https://bob:[email protected]/place",
  "http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64"
]

Enum.each(test_cases, fn str ->
  IO.puts "\n#{str}"
  IO.inspect URI.parse(str)
end)


open System
open System.Text.RegularExpressions

let writeline n v = if String.IsNullOrEmpty(v) then () else printfn "%-15s %s" n v

let toUri = fun s -> Uri(s.ToString())
let urisFromString = (Regex(@"\S+").Matches) >> Seq.cast >> (Seq.map toUri)

urisFromString """
    foo://example.com:8042/over/there?name=ferret#nose
    urn:example:animal:ferret:nose
    jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true
    ftp://ftp.is.co.za/rfc/rfc1808.txt
    http://www.ietf.org/rfc/rfc2396.txt#header1
    ldap://[2001:db8::7]/c=GB?objectClass?one
    mailto:[email protected]
    news:comp.infosystems.www.servers.unix
    tel:+1-816-555-1212
    telnet://192.0.2.16:80/
    urn:oasis:names:specification:docbook:dtd:xml:4.1.2
    """
|> Seq.iter (fun u ->
    writeline "\nURI:" (u.ToString())
    writeline "     scheme:" (u.Scheme)
    writeline "     host:" (u.Host)
    writeline "     port:" (if u.Port < 0 then "" else u.Port.ToString())
    writeline "     path:" (u.AbsolutePath)
    writeline "     query:" (if u.Query.Length > 0 then u.Query.Substring(1) else "")
    writeline "     fragment:" (if u.Fragment.Length > 0 then u.Fragment.Substring(1) else "")
    )


package main

import (
	"fmt"
	"log"
	"net"
	"net/url"
)

func main() {
	for _, in := range []string{
		"foo://example.com:8042/over/there?name=ferret#nose",
		"urn:example:animal:ferret:nose",
		"jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true",
		"ftp://ftp.is.co.za/rfc/rfc1808.txt",
		"http://www.ietf.org/rfc/rfc2396.txt#header1",
		"ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
		"mailto:[email protected]",
		"news:comp.infosystems.www.servers.unix",
		"tel:+1-816-555-1212",
		"telnet://192.0.2.16:80/",
		"urn:oasis:names:specification:docbook:dtd:xml:4.1.2",

		"ssh://[email protected]",
		"https://bob:[email protected]/place",
		"http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64",
	} {
		fmt.Println(in)
		u, err := url.Parse(in)
		if err != nil {
			log.Println(err)
			continue
		}
		if in != u.String() {
			fmt.Printf("Note: reassmebles as %q\n", u)
		}
		printURL(u)
	}
}

func printURL(u *url.URL) {
	fmt.Println("    Scheme:", u.Scheme)
	if u.Opaque != "" {
		fmt.Println("    Opaque:", u.Opaque)
	}
	if u.User != nil {
		fmt.Println("    Username:", u.User.Username())
		if pwd, ok := u.User.Password(); ok {
			fmt.Println("    Password:", pwd)
		}
	}
	if u.Host != "" {
		if host, port, err := net.SplitHostPort(u.Host); err == nil {
			fmt.Println("    Host:", host)
			fmt.Println("    Port:", port)
		} else {
			fmt.Println("    Host:", u.Host)
		}
	}
	if u.Path != "" {
		fmt.Println("    Path:", u.Path)
	}
	if u.RawQuery != "" {
		fmt.Println("    RawQuery:", u.RawQuery)
		m, err := url.ParseQuery(u.RawQuery)
		if err == nil {
			for k, v := range m {
				fmt.Printf("        Key: %q Values: %q\n", k, v)
			}
		}
	}
	if u.Fragment != "" {
		fmt.Println("    Fragment:", u.Fragment)
	}
}


import java.net.URI

[
    "foo://example.com:8042/over/there?name=ferret#nose",
    "urn:example:animal:ferret:nose",
    "jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true",
    "ftp://ftp.is.co.za/rfc/rfc1808.txt",
    "http://www.ietf.org/rfc/rfc2396.txt#header1",
    "ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
    "mailto:[email protected]",
    "news:comp.infosystems.www.servers.unix",
    "tel:+1-816-555-1212",
    "telnet://192.0.2.16:80/",
    "urn:oasis:names:specification:docbook:dtd:xml:4.1.2"
].each { String url ->

    // magic happens here
    URI u = url.toURI()

    // Results displayed here
    println """
            |Parsing $url
            |    scheme   = ${u.scheme}
            |    domain   = ${u.host}
            |    port     = ${(u.port + 1) ? u.port : 'default' }
            |    path     = ${u.path ?: u.schemeSpecificPart}
            |    query    = ${u.query}
            |    fragment = ${u.fragment}""".stripMargin()
}


module Main (main) where

import           Data.Foldable (for_)
import           Network.URI
                    ( URI
                    , URIAuth
                    , parseURI
                    , uriAuthority
                    , uriFragment
                    , uriPath
                    , uriPort
                    , uriQuery
                    , uriRegName
                    , uriScheme
                    , uriUserInfo
                    )

uriStrings :: [String]
uriStrings =
    [ "https://bob:[email protected]/place"
    , "foo://example.com:8042/over/there?name=ferret#nose"
    , "urn:example:animal:ferret:nose"
    , "jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true"
    , "ftp://ftp.is.co.za/rfc/rfc1808.txt"
    , "http://www.ietf.org/rfc/rfc2396.txt#header1"
    , "ldap://[2001:db8::7]/c=GB?objectClass?one"
    , "mailto:[email protected]"
    , "news:comp.infosystems.www.servers.unix"
    , "tel:+1-816-555-1212"
    , "telnet://192.0.2.16:80/"
    , "urn:oasis:names:specification:docbook:dtd:xml:4.1.2"
    ]

trimmedUriScheme :: URI -> String
trimmedUriScheme = init . uriScheme

trimmedUriUserInfo :: URIAuth -> Maybe String
trimmedUriUserInfo uriAuth =
    case uriUserInfo uriAuth of
        [] -> Nothing
        userInfo -> if last userInfo == '@' then Just (init userInfo) else Nothing

trimmedUriPath :: URI -> String
trimmedUriPath uri = case uriPath uri of '/' : t -> t; p -> p

trimmedUriQuery :: URI -> Maybe String
trimmedUriQuery uri = case uriQuery uri of '?' : t -> Just t; _ -> Nothing

trimmedUriFragment :: URI -> Maybe String
trimmedUriFragment uri = case uriFragment uri of '#' : t -> Just t; _ -> Nothing

main :: IO ()
main = do
    for_ uriStrings $ \uriString -> do
        case parseURI uriString of
            Nothing -> putStrLn $ "Could not parse" ++ uriString
            Just uri -> do
                putStrLn uriString
                putStrLn $ "  scheme = " ++ trimmedUriScheme uri
                case uriAuthority uri of
                    Nothing -> return ()
                    Just uriAuth -> do
                        case trimmedUriUserInfo uriAuth of
                            Nothing -> return ()
                            Just userInfo ->  putStrLn $ "  user-info = " ++ userInfo
                        putStrLn $ "  domain = " ++ uriRegName uriAuth
                        putStrLn $ "  port = " ++ uriPort uriAuth
                putStrLn $ "  path = " ++ trimmedUriPath uri
                case trimmedUriQuery uri of
                    Nothing -> return ()
                    Just query -> putStrLn $ "  query = " ++ query
                case trimmedUriFragment uri of
                    Nothing -> return ()
                    Just fragment ->  putStrLn $ "  fragment = " ++ fragment
        putStrLn ""


split=:1 :0
  ({. ; ] }.~ 1+[)~ i.&m
)

uriparts=:3 :0
  'server fragment'=. '#' split y
  'sa query'=. '?' split server
  'scheme authpath'=. ':' split sa
  scheme;authpath;query;fragment
)

queryparts=:3 :0
  (0<#y)#<;._1 '?',y
)

authpathparts=:3 :0
  if. '//' -: 2{.y do.
    split=. <;.1 y
    (}.1{::split);;2}.split
  else.
    '';y
  end.
)

authparts=:3 :0
  if. '@' e. y do.
    'userinfo hostport'=. '@' split y
  else.
    hostport=. y [ userinfo=.''
  end.
  if. '[' = {.hostport do.
     'host_t port_t'=. ']' split hostport
     assert. (0=#port_t)+.':'={.port_t
     (':' split userinfo),(host_t,']');}.port_t
  else.
     (':' split userinfo),':' split hostport
  end.
)

taskparts=:3 :0
  'scheme authpath querystring fragment'=. uriparts y
  'auth path'=. authpathparts authpath
  'user creds host port'=. authparts auth
  query=. queryparts querystring
  export=. ;:'scheme user creds host port path query fragment'
  (#~ 0<#@>@{:"1) (,. do each) export
)


import java.net.URI;
import java.net.URISyntaxException;
public class WebAddressParser{
    public static void main(String[] args){
        parseAddress("foo://example.com:8042/over/there?name=ferret#nose");
        parseAddress("urn:example:animal:ferret:nose");
    }

    static void parseAddress(String a){
        System.out.println("Parsing " + a);
        try{

            // this line does the work
            URI u = new URI(a);

            System.out.println("\tscheme = " + u.getScheme());
            System.out.println("\tdomain = " + u.getHost());
            System.out.println("\tport = " + (-1==u.getPort()?"default":u.getPort()));
            System.out.println("\tpath = " + (null==u.getPath()?u.getSchemeSpecificPart():u.getPath()));
            System.out.println("\tquery = " + u.getQuery());
            System.out.println("\tfragment = " + u.getFragment());
        }
        catch (URISyntaxException x){
            System.err.println("Oops: " + x);
        }
    }
}


(function (lstURL) {

    var e = document.createElement('a'),
        lstKeys = [
            'hash',
            'host',
            'hostname',
            'origin',
            'pathname',
            'port',
            'protocol',
            'search'
        ],

        fnURLParse = function (strURL) {
            e.href = strURL;

            return lstKeys.reduce(
                function (dct, k) {
                    dct[k] = e[k];
                    return dct;
                }, {}
            );
        };

    return JSON.stringify(
        lstURL.map(fnURLParse),
        null, 2
    );

})([
  "foo://example.com:8042/over/there?name=ferret#nose",
  "urn:example:animal:ferret:nose",
  "jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true",
  "ftp://ftp.is.co.za/rfc/rfc1808.txt",
  "http://www.ietf.org/rfc/rfc2396.txt#header1",
  "ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
  "mailto:[email protected]",
  "news:comp.infosystems.www.servers.unix",
  "tel:+1-816-555-1212",
  "telnet://192.0.2.16:80/",
  "urn:oasis:names:specification:docbook:dtd:xml:4.1.2",
  "ssh://[email protected]",
  "https://bob:[email protected]/place",
  "http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64"
]);


using Printf, URIParser

const FIELDS = names(URI)

function detailview(uri::URI, indentlen::Int=4)
    indent = " "^indentlen
    s = String[]
    for f in FIELDS
        d = string(getfield(uri, f))
        !isempty(d) || continue
        f != :port || d != "0" || continue
        push!(s, @sprintf("%s%s:  %s", indent, string(f), d))
    end
    join(s, "\n")
end

test = ["foo://example.com:8042/over/there?name=ferret#nose",
        "urn:example:animal:ferret:nose",
        "jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true",
        "ftp://ftp.is.co.za/rfc/rfc1808.txt",
        "http://www.ietf.org/rfc/rfc2396.txt#header1",
        "ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
        "mailto:[email protected]",
        "news:comp.infosystems.www.servers.unix",
        "tel:+1-816-555-1212",
        "telnet://192.0.2.16:80/",
        "urn:oasis:names:specification:docbook:dtd:xml:4.1.2",
        "This is not a URI!",
        "ssh://[email protected]",
        "https://bob:[email protected]/place",
        "http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64"]

isfirst = true
for st in test
    if isfirst
        isfirst = false
    else
        println()
    end
    println("Attempting to parse\n  \"", st, "\" as a URI:")
    uri = try
        URI(st)
    catch
        println("URIParser failed to parse this URI, is it OK?")
        continue
    end
    print("This URI is parsable ")
    if isvalid(uri)
        println("and appears to be valid.")
    else
        println("but may be invalid.")
    end
    println(detailview(uri))
end


// version 1.1.2

import java.net.URL
import java.net.MalformedURLException

fun parseUrl(url: String) {
    var u: URL
    var scheme: String
    try {
        u = URL(url)
        scheme = u.protocol
    }
    catch (ex: MalformedURLException) {
        val index = url.indexOf(':')
        scheme = url.take(index)
        u = URL("http" + url.drop(index))
    }
    println("Parsing $url")
    println("  scheme   =  $scheme")

    with(u) {
        if (userInfo != null) println("  userinfo =  $userInfo")
        if (!host.isEmpty())  println("  domain   =  $host")
        if (port != -1)       println("  port     =  $port")
        if (!path.isEmpty())  println("  path     =  $path")
        if (query != null)    println("  query    =  $query")
        if (ref != null)      println("  fragment =  $ref")
    }
    println()
}

fun main(args: Array<String>){
    val urls = arrayOf(
        "foo://example.com:8042/over/there?name=ferret#nose",
        "urn:example:animal:ferret:nose",
        "jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true",
        "ftp://ftp.is.co.za/rfc/rfc1808.txt",
        "http://www.ietf.org/rfc/rfc2396.txt#header1",
        "ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two",
        "mailto:[email protected]",
        "news:comp.infosystems.www.servers.unix",
        "tel:+1-816-555-1212",
        "telnet://192.0.2.16:80/",
        "urn:oasis:names:specification:docbook:dtd:xml:4.1.2",
        "ssh://[email protected]",
        "https://bob:[email protected]/place",
        "http://example.com/?a=1&b=2+2&c=3&c=4&d=%65%6e%63%6F%64%65%64"
    )
    for (url in urls) parseUrl(url)
}


local url = require('socket.url')

local tests = {
  'foo://example.com:8042/over/there?name=ferret#nose',
  'urn:example:animal:ferret:nose',
  'jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true',
  'ftp://ftp.is.co.za/rfc/rfc1808.txt',
  'http://www.ietf.org/rfc/rfc2396.txt#header1',
  'ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two',
  'mailto:[email protected]',
  'news:comp.infosystems.www.servers.unix',
  'tel:+1-816-555-1212',
  'telnet://192.0.2.16:80/',
  'urn:oasis:names:specification:docbook:dtd:xml:4.1.2'
}

for _, test in ipairs(tests) do
  local parsed = url.parse(test)

  io.write('URI: ' .. test .. '\n')

  for k, v in pairs(parsed) do
    io.write(string.format('  %s: %s\n', k, v))
  end

  io.write('\n')
end


Module checkit {
      any=lambda (z$)->{=lambda z$ (a$)->instr(z$,a$)>0}
      one=lambda (z$)->{=lambda z$ (a$)->z$=a$}
      number$="0123456789"

      series=Lambda  -> {
                  func=Array([])
                  =lambda  func (&line$, &res$)->{
                        if line$="" then exit
                        k=each(func)
                        def p=0,ok as boolean
                        while k {
                              ok=false :  p++ :  f=array(k)
                              if not f(mid$(line$,p,1)) then exit
                              ok=true
                        }
                        if ok then res$=left$(line$, p) : line$=mid$(line$, p+1)
                        =ok
                  }
      }

      is_any=lambda series, any  (c$) ->series(any(c$))
      is_one=lambda series, one  (c$) ->series(one(c$))
      Is_Alpha=series(lambda (a$)-> a$ ~ "[a-zA-Z]")
      Is_digit=series(any(number$))
      Is_hex=any(number$+"abcdefABCDEF")

      optionals=Lambda  -> {
                  func=Array([])
                  =lambda  func (&line$, &res$)->{
                        k=each(func)
                        def ok as boolean
                        while k {
                              f=array(k)
                              if f(&line$,&res$) then ok=true : exit
                        }
                        =ok
                  }
      }
      repeated=Lambda  (func)-> {
                  =lambda  func (&line$, &res$)->{
                        def ok as boolean, a$
                        res$=""
                        do {
                              sec=len(line$)
                              if not func(&line$,&a$) then exit
                              res$+=a$
                              ok=true
                        } until line$="" or sec=len(line$)
                        =ok
                  }
      }

      oneAndoptional=lambda (func1, func2) -> {
            =lambda  func1, func2 (&line$, &res$)->{
                              def ok as boolean, a$
                              res$=""
                              if not func1(&line$,&res$) then exit
                              if func2(&line$,&a$) then res$+=a$
                              =True
                        }
      }
      many=Lambda  -> {
                  func=Array([])
                  =lambda  func (&line$, &res$)->{
                        k=each(func)
                        def p=0,ok as boolean, acc$
                        oldline$=line$
                        while k  {
                              ok=false
                              res$=""
                              if line$="" then exit
                              f=array(k)
                              if not f(&line$,&res$) then exit
                              acc$+=res$
                              ok=true
                         }
                        if not ok then {line$=oldline$}  else res$=acc$
                        =ok
                  }
      }
      is_safe=series(any("[email protected]&"))
      Is_extra=series(any("!*'(),"+chr$(34)))
      Is_Escape=series(any("%"), is_hex, is_hex)
      \\Is_reserved=series(any("=;/#?: "))
      is_xalpha=optionals(Is_Alpha, is_digit, is_safe, is_extra, is_escape)
      is_xalphas=oneAndoptional(is_xalpha,repeated(is_xalpha))
      is_xpalpha=optionals(is_xalpha, is_one("+"))
      is_xpalphas=oneAndoptional(is_xpalpha,repeated(is_xpalpha))
      Is_ialpha=oneAndoptional(Is_Alpha,repeated(is_xpalphas))
      is_fragmentid=lambda is_xalphas (&lines$, &res$) -> {
            =is_xalphas(&lines$, &res$)
      }
      is_search=oneAndoptional(is_xalphas, repeated(many(series(one("+")), is_xalphas)))
      is_void=lambda (f)-> {
            =lambda f (&oldline$, &res$)-> {
                  line$=oldline$
                  if f(&line$, &res$) then {oldline$=line$ } else res$=""
                  =true
            }
      }
      is_scheme=is_ialpha
      is_path=repeated(oneAndoptional(is_void(is_xpalphas), series(one("/"))))
      is_uri=oneAndoptional(many(is_scheme, series(one(":")), is_path), many(series(one("?")),is_search))
      is_fragmentaddress=oneAndoptional(is_uri, many(series(one("#")),is_fragmentid ))

      data "foo://example.com:8042/over/there?name=ferret#nose"
      data "urn:example:animal:ferret:nose"
      data "jdbc:mysql://test_user:[email protected]:3306/sakila?profileSQL=true "
      data "ftp://ftp.is.co.za/rfc/rfc1808.txt"
      data "http://www.ietf.org/rfc/rfc2396.txt#header1"
      data "ldap://[2001:db8::7]/c=GB?objectClass=one&objectClass=two"
      data "mailto:John.D[email protected]"
      data "tel:+1-816-555-1212"
      data "telnet://192.0.2.16:80/"
      data "urn:oasis:names:specification:docbook:dtd:xml:4.1.2"

      while not empty {
            read What$
            pen 15 {
                  Print What$
            }
            a$=""
            If is_scheme(&What$, &a$) Then  Print "Scheme=";a$ : What$=mid$(What$,2)
            If is_path(&What$, &a$) Then {
                  count=0
                  while left$(a$, 1)="/" { a$=mid$(a$,2): count++}
                  if count>1 then {
                        domain$=leftpart$(a$+"/", "/")
                        a$=rightpart$(a$,"/")
                        if domain$<>"" Then Print "Domain:";Domain$
                        if a$<>"" Then Print "Path:";a$
                  } else.if  left$(What$,1) =":" then {
                        Print "path:";a$+What$: What$=""
                  } Else Print  "Data:"; a$

            }

            if left$(What$,1) =":" then {
                  is_number=repeated(is_digit)
                  What$=mid$(What$,2): If is_number(&What$, &a$) Then Print "Port:";a$
                  if not left$(What$,1)="/" then  exit
                  If is_path(&What$, &a$) Then {
                        while left$(a$, 1)="/" { a$=mid$(a$,2)}
                        if a$<>"" Then Print "Path:";a$
                  }
            }
            if left$(What$, 1)="?" then {
                        What$=mid$(What$,2)
                        If is_search(&What$, &a$) Then  {
                        v$=""
                        if left$(What$, 1)="=" then {
                              What$=mid$(What$,2)
                              If is_search(&What$, &v$) Then  Print "Query:";a$;"=";v$
                        }  else Print "Query:";a$
                        }
            }
            While  left$(What$, 1)="#"  {
            What$=mid$(What$,2)
            if not is_xalphas(&What$, &a$) Then exit
            Print "fragment:";a$
            }
            if What$<>"" Then Print "Data:"; What$
      }
}
Checkit